Closed liangjiawei closed 2 years ago
参考一下文档的包路径映射功能
我读了文档,但是有点不理解,例如:被测类使用接口为DemoService,第三方包实现类为DemoServiceImpl,那我使用的DemoServiceImplMock需要implement DemoService吗?
不用,原理上来说,TestableMock只是需要将被测类、测试类和Mock容器类之间建立关联,然后就可以自动进行调用匹配和替换了。目前这个关联是通过名称约定来建立的,就是默认在同包下命名符合业务类Test.Mock
或者业务类Mock
的类型就会被识别为Mock容器类。
只是当由于某些情况导致无法用默认路径和名称定义Mock容器类是时候,就要用到一些额外的手段,包括使用@MockWith
注解和配置文件(添加包路径映射)。
那这种就带来了另外一个问题,被测类里面这个DemoService引用需要在使用前赋值, 如果这个引用赋值,引用本身是null, 那 demoService.doSomething() 后面的方法根本不会走
我使用的是这个
PrivateAccessor.set(被测类, "demoService", new DependServiceImplMock());
就会出现报错
java.lang.IllegalArgumentException : Can not set DemoService field 被测类.demoService to DemoMock
这个被测类里面引用怎样才能实现赋值。
不用创建DependServiceImplMock
类替换DemoService
里的成员对象。Testable的Mock机制是直接替换调用,而不是替换对象,Mock类的作用仅仅是一个存放要替换的Mock方法集合的容器,所以称为是“Mock容器类”。
比如DemoService
类里有一个dependService.something()
调用,希望在单元测试的时候被替换掉。只需要创建DemoServiceMock
类型(包含DemoService
类所需的Mock方法集合),在里面定义一个名字和参数与something()
相同的方法,加上@MockMethod(targetClass = DependService.class)
注解,单元测试运行的时候就会自动把所有DemoService
类里对DependService类型something()方法的调用统统替换掉。不需要考虑如何注入Mock对象的问题。
这种Mock方式和主流的Mock工具差别比较大,如果已经习惯了基于对象的Mock方式,可能刚开始会不太适应。
@linfan 我的问题还没解决,按照上面的您的回答。我不对被测试类里面的引用做初始化,但是如果不做的话,那些引用都是null,直接报空指针错误,后面的demoService.doSomething() 根本不会走
可以用PrivateAccessor+OmniConstructor直接在测试用例创建被测对象以后,把其中的成员字段直接初始化赋值。
接口Mock我今天也碰到了Mock失败的问题。
我的问题是Mock的方法出入参和原接口不一致导致,修改一致后Mock成功。
被测试类中的私有变量(特指接口)是不需要在测试类中初始化的,直接在测试类中Mock该接口的方法就行。
请教一个问题,单元测试类A,类A有一个私有成员spring bean 接口B, B的实现类C,但是C是在另一个模块下。A模块下写单元测试无法初始化接口B。这种情况怎么处理的?