简介
在实际的开发中,单元测试是不可避免的一环。很多时候针对复杂的类依赖和调用关系的场景(某个方法可能会层层调用其他类的方法,且逻辑复杂),造数据去测这种场景的代码,是非常难受且难以全覆盖的。针对这样的问题,mockito的工具可以很好的解决。mockito工具可以只针对测试你当前测试的方法的主要平层逻辑,而不用去关注当前方法的内部调用的其他方法(当前私有方法还不能实现)。因为通过mockito可以给内部调用的方法创建一个虚拟对象,根据测试的需要返回需要的数据,不用真正执行调用其他方法的真正逻辑。
常用的注解
@injectMock
主要是用于来创建你需要测试的对象,
@Mock
主要是用来创建在测试对象中使用的对象,也就是虚拟的对象。
@Spy
主要是用来创建在测试对象中使用的对象,它是真实的对象。
不管是@Mock还是,@Spy是不受spring托管的。
demo 1 在测试的方法内调用其他类的方法
先建两个service层的类 CompanyServiceImpl和PersonServiceImpl,PersonServiceImpl.getUserAllInfo()方法会调用CompanyServiceImpl.getCompanyInfo();
package bear.tw.service; public class PersonServiceImpl { private CompanyServiceImpl companyService = new CompanyServiceImpl(); public void getUserAllInfo(Long userId){ String companyNameByUserId = companyService.getCompanyNameByUserId(userId); System.out.println(companyNameByUserId); System.out.println("current userId is:" + userId); } }
package bear.tw.service; public class CompanyServiceImpl { public String getCompanyNameByUserId(Long userId){ String name = "real company "; return name; } }
单元测试类
package bear.tw; import bear.tw.service.CompanyServiceImpl; import bear.tw.service.PersonServiceImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import static org.mockito.Mockito.*; ; @RunWith(MockitoJUnitRunner.class) public class PersonServiceTest { @InjectMocks private PersonServiceImpl personService; @Mock private CompanyServiceImpl companyService; @Test public void getUserAllInfo(){ when(companyService.getCompanyNameByUserId(anyLong())).thenReturn("virtual company 1"); personService.getUserAllInfo(1l); } }
测试方法getUserAllInfo的结果是:
根据截图的结果可知 companyService.getCompanytInfo的执行结果是测试方法的里设置的 虚拟值,而不是真实的执行结果。表明调用的是虚拟的对象方法
demo2 当前测试方法调用同类的其他方法(将被调用的方法虚拟为一个方法)
在PersonServiceImpl中添加另外一个方法 countUser ,然后在getUserAllInfo()中调用
package bear.tw.service; public class PersonServiceImpl { private CompanyServiceImpl companyService = new CompanyServiceImpl(); public void getUserAllInfo(Long userId){ String companyNameByUserId = companyService.getCompanyNameByUserId(userId); System.out.println(companyNameByUserId); System.out.println("current userId is:" + userId); System.out.println(countUser()); } public int countUser(){ return 1; } }
然后修改测试类
@Test public void getUserAllInfo2(){ when(companyService.getCompanyNameByUserId(anyLong())).thenReturn("virtual company 2"); PersonServiceImpl spy = spy(personService); doReturn(2).when(spy).countUser(); spy.getUserAllInfo(1l); }
测试结果
从测试结果看,companyService对象的虚拟对象成功了, PersonServiceImpl的countUser方法的虚拟对象也执行成功了。