单元测试—Mockito设置方法返回值


Mockito 是一个模拟测试框架,主要功能是在单元测试中模拟类/对象的行为。

单元测试 – Mockito设置方法返回值

1、thenReturn与doReturn

thenReturn 用来指定特定函数和参数调用的返回值。

thenReturn 中可以指定多个返回值。在调用时返回值依次出现。若调用次数超过返回值的数量,再次调用时返回最后一个返回值。

doReturn 的作用和thenReturn相同,但使用方式不同(doReturn(1).when(random).nextInt();)

@RunWith(MockitoJUnitRunner.class)
public class Mocktio {
    @Mock
    private ExampleService exampleService;

    @Test
    public void test_spy() {
        MockitoAnnotations.openMocks(this);
        when(exampleService.add(anyInt(), anyInt())).thenReturn(1, 2, 3);

        Assert.assertEquals(1, exampleService.add(1, 2));
        Assert.assertEquals(2, exampleService.add(9, 7));
        Assert.assertEquals(3, exampleService.add(10, 12));
        Assert.assertEquals(3, exampleService.add(11, 6));
        Assert.assertEquals(3, exampleService.add(7, 3));

    }

    class ExampleService {

        int add(int a, int b) {
            System.out.println("方法调用被执行");
            return a+b;
        }

    }
}

2、thenThrow与doThrow

thenThrow用来让函数调用抛出异常。thenThrow 中可以指定多个异常。在调用时异常依次出现。若调用次数超过异常的数量,再次调用时抛出最后一个异常。

对应返回类型是 void 的函数,thenThrow 是无效的,要使用doThrow。doThrow(new RuntimeException(“异常”)).when(exampleService).hello();

@RunWith(MockitoJUnitRunner.class)
public class Mocktio {
    @Mock
    private ExampleService exampleService;

    @Test
    public void test_spy() {
        MockitoAnnotations.openMocks(this);
        when(exampleService.add(anyInt(),anyInt())).thenThrow(new RuntimeException("异常"));

        try {
            exampleService.add(1, 2);
            Assert.fail();  // 上面会抛出异常,所以不会走到这里
        } catch (Exception ex) {
            Assert.assertTrue(ex instanceof RuntimeException);
            Assert.assertEquals("异常", ex.getMessage());
        }

        doThrow(new RuntimeException("异常")).when(exampleService).addPrint(1, 2);
        try {
            exampleService.addPrint(1, 2);
            Assert.fail();  // 上面会抛出异常,所以不会走到这里
        } catch (Exception ex) {
            Assert.assertTrue(ex instanceof RuntimeException);
            Assert.assertEquals("异常", ex.getMessage());
        }

    }

    class ExampleService {

        int add(int a, int b) {
            System.out.println("方法调用被执行");
            return a+b;
        }

        void addPrint(int a, int b) {
            System.out.println("方法调用被执行");
        }
    }
}

3、thenAnswer

then 和 thenAnswer 的效果是一样的。它们的参数是实现 Answer 接口的对象,在改对象中可以获取调用参数,自定义返回值。

我们在对Mybatisinsert生成自增主键时的情况可以使用

Mockito.when(areaService.insert(any())).thenAnswer((Answer<Integer>) invocation -> {
            Object[] args = invocation.getArguments();
            // 获取参数
            AreaEntity areaEntity = (AreaEntity) args[0];

            areaEntity.setId(1);

            return 1;
        });

when(…)thenAnswer(…)的作用有以下三种

1、他可以返回一个值也可以抛出异常

2、他可以获取到传入的参数

3、他可以对参数进行判断,决定下一步动作

@Test
public void testThenAnswer() {
    List mockedList = mock(List.class);
    when(mockedList.size()).thenReturn(20);
    when(mockedList.get(anyInt())).thenAnswer((Answer<String>) invocation -> {
        Object[] args = invocation.getArguments();
        In
            
            teger index = (Integer) args[0];
        if (index == 0) {
            return "foo";
        } else if (index == 1) {
            return "bar";
        } else if (index < 10) {
            return "baz";
        } else if (index < 20) {
            return "qux";
        } else {
            throw new IndexOutOfBoundsException();
        }
    });

    Assert.assertEquals(20, mockedList.size());
    Assert.assertEquals("foo", mockedList.get(0));
    Assert.assertEquals("bar", mockedList.get(1));
    Assert.assertEquals("baz", mockedList.get(8));
    Assert.assertEquals("qux", mockedList.get(16));

    thrown.expect(IndexOutOfBoundsException.class);
    mockedList.get(20);
}

4、引用

Mockito 指南

教你使用Mock完成单元测试

springboot test


文章作者: WangQingLei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WangQingLei !
  目录