springboot单元测试mock依赖的类实践

引入包,测试版本:<powermock.version>1.7.1</powermock.version>

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>

测试类

//aService类的findStudyInfoById方法内部实现,调用了bDao的方法,
//单元测试只需关心aService当前层的正确性,bDao的正确性由它自己的单元测试保证,
//所以需要模拟一个假的bDao场景,来配合完成aService的单元测试
public class MockTest {

    //注入要测试类,注意这里注入写实现类,不能写接口注入
    @InjectMocks
    private AServiceImpl aService;

    //mock这个类,帮助测试aService,而不测试实际的bDao
    @Mock
    private BDao bDao;

    //初始化测试数据
    @Before
    public void initMock() {
        MockitoAnnotations.initMocks(this);
        Student student = new Student;
        student.setName("测试");
        student.setId(1);
        //初始化mock类的场景,如果传入一个int,返回自己mock的student数据
        when(bDao.findStudyInfoById(anyInt())).thenReturn(student);
    }

    @Test
    public void findStudyInfoById() throws Exception {
        List<Student> students = aService.findStudyInfoById(1);
        Assert.assertTrue(rstudents.size()==1);
    }

}

附遇到的问题:

问题一:mock void方法,不带返回值的方法

AService aService = Mockito.mock(AService.class);
        Mockito.doAnswer(new Answer<Object>() {
            public Object answer(InvocationOnMock invocation) {
                Object[] args = invocation.getArguments();
                return "执行了" + args;
            }
        }).when(aService).findStudent(anyString());

问题二:错误提示

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

解决:比如错误的是这样写的:

when(aService.findStudent("xiaoming",anyList()));

修改一下传入参数,有一个any参数,其中非any参数,都加上eq(),比如"xiaoming",这个就是确定的参数,不是any统配一些类型

when(aService.findStudent(eq("xiaoming"),eq(anyList())));

一般不需要加eq(),但是如果有一个参数需要加,其他参数也应该看看是否需要加上eq()。

问题三:mock类全局变量

引入pom

 <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-reflect</artifactId>
            <version>1.7.1</version>
            <scope>test</scope>
        </dependency>

使用方法

Whitebox.setInternalState(aService, "mockJzt",1);

这个就mock了,aService类的mockJzt变量,设置为1了

问题四:测试方法内调用多个方法,mock其中几个,剩下的调用不mock,使用真实调用

比如测试A类的findStudent方法,findStudent方法里面调用B类的a,b,c三个方法,mock了a和b方法,调用c真实方法

when(B.a("")).thenReturn(false);
when(B.a("")).thenReturn(false);
when(B.c("")).thenReturn(B.c());

重点就是thenReturn,这个后面如果mock可以返回自己mock的数据,如果不mock可以调用真实的方法,返回真实的值。(需要引入类@Autowire注入使用)

猜你喜欢

转载自blog.csdn.net/Mint6/article/details/93490063