请教一个 Mock 单元测试问题?

2022-09-10 13:27:28 +08:00
 gzk329

如图所示,一个测试类中,有一个 @InjectMock 桩点 桩点依赖一个 bean 需要真实方法 所以打了 @Spy 注解,那么这个 bean 的依赖该怎么表示?我需要 @Mock --->>> 注入 bean ---->>> 注入 桩点

1925 次点击
所在节点    Java
11 条回复
JasonLaw
2022-09-10 15:08:54 +08:00
首先我会有一些疑问,为什么你一定要 @Spy ?为什么你需要这个依赖的真实行为?
JasonLaw
2022-09-10 15:19:10 +08:00
如果你只是想要达成这样的行为,多级依赖注入,你可以看一下 https://stackoverflow.com/questions/6300439/multiple-levels-of-mock-and-injectmocks

不过还是那句话,不建议这么做,当你这么做的时候,不然你的代码有问题,不然你的单元测试有问题。
JasonLaw
2022-09-10 15:21:46 +08:00
chihiro2014
2022-09-10 15:28:37 +08:00
一般不需要 spy ,能 mock 的都能 mock 出来,如果是私有方法,那通常也是走公有方法的逻辑,调用私有。有参构造的 mock 我觉得 mock 不来
chihiro2014
2022-09-11 23:39:55 +08:00
来更新下,刚好这两天单元测试,又写到了无法吐槽的地方,于是一激灵,就用了楼主说的 spy ,大概场景是 Resttemplate 部分需要设置权限相关的一些参数。我们这边代码比较古早,resttemplate 直接 new 出来,而不是 autowired ,不得不感叹,代码写的烂,mock 都 mock 不动。。。
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 的程度比较深。也建议检查下代码是否有问题。最近就是被这个所干扰了
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();
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
gzk329
2022-09-14 21:24:54 +08:00
@JasonLaw 你好 其实我的业务场景是 一个 Class A 测试类 @InjectMock 中有一个文件上传下载工具类 我测试需要这个工具类使用他自己真实的方法 所以我就对其使用了 @Spy 这个工具类中又有依赖的类 我也需要对这些类使用 mock 模拟数据
我现在的解决方案是 @Resource 和 @InjectMock 一起使用了 既直接注入了测试类对象 同时 又能 mock 其中的一些依赖
gzk329
2022-09-14 21:26:33 +08:00
@chihiro2014 我的场景是三层的 我现在是使用 @Resource 和 @InjectMock 一起使用 可以达到我要的效果 供参考
chihiro2014
2022-09-14 21:36:55 +08:00
@gzk329 遇上这种需要文件 io 的操作,其实特别不好 mock

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/879104

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX