如图所示,一个测试类中,有一个 @InjectMock 桩点 桩点依赖一个 bean 需要真实方法 所以打了 @Spy 注解,那么这个 bean 的依赖该怎么表示?我需要 @Mock --->>> 注入 bean ---->>> 注入 桩点
2
JasonLaw 2022-09-10 15:19:10 +08:00
如果你只是想要达成这样的行为,多级依赖注入,你可以看一下 https://stackoverflow.com/questions/6300439/multiple-levels-of-mock-and-injectmocks
不过还是那句话,不建议这么做,当你这么做的时候,不然你的代码有问题,不然你的单元测试有问题。 |
3
JasonLaw 2022-09-10 15:21:46 +08:00
|
4
chihiro2014 2022-09-10 15:28:37 +08:00
一般不需要 spy ,能 mock 的都能 mock 出来,如果是私有方法,那通常也是走公有方法的逻辑,调用私有。有参构造的 mock 我觉得 mock 不来
|
5
chihiro2014 2022-09-11 23:39:55 +08:00
来更新下,刚好这两天单元测试,又写到了无法吐槽的地方,于是一激灵,就用了楼主说的 spy ,大概场景是 Resttemplate 部分需要设置权限相关的一些参数。我们这边代码比较古早,resttemplate 直接 new 出来,而不是 autowired ,不得不感叹,代码写的烂,mock 都 mock 不动。。。
|
6
chihiro2014 2022-09-11 23:46:40 +08:00
感谢下楼主给的经验,这里来表示下我的看法。
正常情况下,我们写单元测试,以 Spring 为例,配合 Junit 和 Mockito 。 假设测试类为 A ,他里面依赖了 Service B 、 那么正常的写法通常就是 ···code @ExtendsWith(xxxx) public class ATest { @InjectMock A a; @Mock B b; @Test public void testMethod() {} ``` 这种情况往往是代码封装的很好(相对来说),所以任意 mock B 提供的返回值。 奇葩情况就是你说的 spy ,需要多层 mock ,那这个时候你就得去查看 B 中用到的依赖,全部 Mock 。 这种就属于 mock 的程度比较深。也建议检查下代码是否有问题。最近就是被这个所干扰了 |
7
zhazi 2022-09-13 10:42:19 +08:00
@JasonLaw
我理解无返回值的测试对象都需要使用 spy 预测对象行为 UserService spyUserService = spy(new UserService(mock(UserDao.class))); spyUserService.saveUser(); verify(spyUserService,times(1)).saveLog(); |
8
JasonLaw 2022-09-13 11:08:44 +08:00
@zhazi #7 如果你要测试的是 UserService 的话,我觉得应该是使用 @InjectMocks ,而不是 @Spy 。
具体可以看一下 https://stackoverflow.com/questions/38567326/is-it-discouraged-to-use-spy-and-injectmocks-on-the-same-field 重点是:@Spy and @Mock are meant for dependencies, and not for the functionality you are testing |
9
gzk329 OP @JasonLaw 你好 其实我的业务场景是 一个 Class A 测试类 @InjectMock 中有一个文件上传下载工具类 我测试需要这个工具类使用他自己真实的方法 所以我就对其使用了 @Spy 这个工具类中又有依赖的类 我也需要对这些类使用 mock 模拟数据
我现在的解决方案是 @Resource 和 @InjectMock 一起使用了 既直接注入了测试类对象 同时 又能 mock 其中的一些依赖 |
10
gzk329 OP |
11
chihiro2014 2022-09-14 21:36:55 +08:00
@gzk329 遇上这种需要文件 io 的操作,其实特别不好 mock
|