package cn.six.mockito;

import android.content.Context;

import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.List;

import edu.emory.mathcs.backport.java.util.Arrays;

import static junit.framework.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.RETURNS_SMART_NULLS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * Created by songzhw on 2017-03-31
 */

public class MockitoTest {

    public class OnlyTwo extends ArgumentMatcher<List> {
        @Override public boolean matches(Object argument) {
            List list = (List) argument;
            return list.size() == 2;
        }
    }

    @Test
    public void testCustomMatcher(){
        List list = mock(List.class);

        // stubb mock执行addAll方法时使用ListOfTwoElementsArgumentMatcher匹配器
        when(list.addAll(argThat(new OnlyTwo()))).thenReturn(true);

        Object o1 = "one";
        Object o2 = "two";
        Object[] ary2 = {o1, o2};
        list.addAll(Arrays.asList(ary2));

        // 验证mock是否add了两个参数
        verify(list).addAll(argThat(new OnlyTwo()));
    }

    @Test
    public void returnsSmartNullsTest() {
        //使用RETURNS_SMART_NULLS参数创建的mock对象，不会抛出NullPointerException异常。
        List list = mock(List.class, RETURNS_SMART_NULLS);
        System.out.println("(A1) = "+list.get(0)); //若上面不加第二参answer， 这里就会NPE
        System.out.println("(A2) = "+list.toArray().length);//=>0   //若上面不加第二参answer， 这里就会NPE
    }
    /*
    (1) = SmartNull returned by this unstubbed method call on a mock:
    list.get(0);
    (2) = 0
    */


    @Test
    public void returnsDeepStubs(){
        //使用RETURNS_SMART_NULLS参数创建的mock对象，不会抛出NullPointerException异常。
        List list = mock(List.class, RETURNS_DEEP_STUBS);
        System.out.println("(B1) = "+list.get(0)); //=>null  //若上面不加第二参answer， 这里就会NPE
        System.out.println("(B2) = "+list.toArray());//=>null   //若上面不加第二参answer， 这里就会NPE
//        System.out.println("(B3) = "+list.toArray().length);//=>NPE crash (加了deep_stubs这里也会NPE)
    }

    @Test
    public void customAnswer(){
        List mockList = mock(List.class);
        //使用Answer来生成我们我们期望的返回
        when(mockList.get(anyInt())).thenAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                Object[] args = invocation.getArguments();
                return "hello world:"+args[0];
            }
        });
        assertEquals("hello world:0",mockList.get(0));
        assertEquals("hello world:999",mockList.get(999));
    }


}

@@ -2844,10 +2844,506 @@
     %7D%0A%0A%0A
+    @Test%0A    public void unstubbed_invocations()%7B%0A        //mock%E5%AF%B9%E8%B1%A1%E4%BD%BF%E7%94%A8Answer%E6%9D%A5%E5%AF%B9%E6%9C%AA%E9%A2%84%E8%AE%BE%E7%9A%84%E8%B0%83%E7%94%A8%E8%BF%94%E5%9B%9E%E9%BB%98%E8%AE%A4%E6%9C%9F%E6%9C%9B%E5%80%BC%0A        List mock = mock(List.class,new Answer() %7B%0A            @Override%0A            public Object answer(InvocationOnMock invocation) throws Throwable %7B%0A                return 999;%0A            %7D%0A        %7D);%0A        //%E4%B8%8B%E9%9D%A2%E7%9A%84get(1)%E6%B2%A1%E6%9C%89%E9%A2%84%E8%AE%BE%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%83%85%E5%86%B5%E4%B8%8B%E4%BC%9A%E8%BF%94%E5%9B%9ENULL%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BD%BF%E7%94%A8%E4%BA%86Answer%E6%94%B9%E5%8F%98%E4%BA%86%E9%BB%98%E8%AE%A4%E6%9C%9F%E6%9C%9B%E5%80%BC%0A        assertEquals(999, mock.get(1));%0A        //%E4%B8%8B%E9%9D%A2%E7%9A%84size()%E6%B2%A1%E6%9C%89%E9%A2%84%E8%AE%BE%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%83%85%E5%86%B5%E4%B8%8B%E4%BC%9A%E8%BF%94%E5%9B%9E0%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BD%BF%E7%94%A8%E4%BA%86Answer%E6%94%B9%E5%8F%98%E4%BA%86%E9%BB%98%E8%AE%A4%E6%9C%9F%E6%9C%9B%E5%80%BC%0A        assertEquals(999,mock.size());%0A    %7D%0A%0A
 %7D%0A

test : Mockito