请教一个 Mock 单元测试问题? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gzk329
V2EX    Java

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

  •  
  •   gzk329 2022 年 9 月 10 日 2685 次点击
    这是一个创建于 1324 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    11 条回复    2022-09-14 21:36:55 +08:00
    JasonLaw
        1
    JasonLaw  
       2022 年 9 月 10 日
    首先我会有一些疑问,为什么你一定要 @Spy ?为什么你需要这个依赖的真实行为?
    JasonLaw
        2
    JasonLaw  
       2022 年 9 月 10 日
    如果你只是想要达成这样的行为,多级依赖注入,你可以看一下 https://stackoverflow.com/questions/6300439/multiple-levels-of-mock-and-injectmocks

    不过还是那句话,不建议这么做,当你这么做的时候,不然你的代码有问题,不然你的单元测试有问题。
    chihiro2014
        4
    chihiro2014  
       2022 年 9 月 10 日
    一般不需要 spy ,能 mock 的都能 mock 出来,如果是私有方法,那通常也是走公有方法的逻辑,调用私有。有参构造的 mock 我觉得 mock 不来
    chihiro2014
        5
    chihiro2014  
       2022 年 9 月 11 日
    来更新下,刚好这两天单元测试,又写到了无法吐槽的地方,于是一激灵,就用了楼主说的 spy ,大概场景是 Resttemplate 部分需要设置权限相关的一些参数。我们这边代码比较古早,resttemplate 直接 new 出来,而不是 autowired ,不得不感叹,代码写的烂,mock 都 mock 不动。。。
    chihiro2014
        6
    chihiro2014  
       2022 年 9 月 11 日
    感谢下楼主给的经验,这里来表示下我的看法。
    正常情况下,我们写单元测试,以 Spring 为例,配合 Junit 和 Mockito 。
    假设测试类为 A ,他里面依赖了 Sevice 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
        7
    zhazi  
       2022 年 9 月 13 日
    @JasonLaw
    我理解无返回值的测试对象都需要使用 spy 预测对象行为
    UserService spyUserService = spy(new UserService(mock(UserDao.class)));
    spyUserService.saveUser();
    verify(spyUserService,times(1)).saveLog();
    JasonLaw
        8
    JasonLaw  
       2022 年 9 月 13 日
    @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
        9
    gzk329  
    OP
       2022 年 9 月 14 日
    @JasonLaw 你好 其实我的业务场景是 一个 Class A 测试类 @InjectMock 中有一个文件上传下载工具类 我测试需要这个工具类使用他自己真实的方法 所以我就对其使用了 @Spy 这个工具类中又有依赖的类 我也需要对这些类使用 mock 模拟数据
    我现在的解决方案是 @Resource 和 @InjectMock 一起使用了 既直接注入了测试类对象 同时 又能 mock 其中的一些依赖
    gzk329
        10
    gzk329  
    OP
       2022 年 9 月 14 日   1
    @chihiro2014 我的场景是三层的 我现在是使用 @Resource 和 @InjectMock 一起使用 可以达到我要的效果 供参考
    chihiro2014
        11
    chihiro2014  
       2022 年 9 月 14 日
    @gzk329 遇上这种需要文件 io 的操作,其实特别不好 mock
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2595 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 10:27 PVG 18:27 LAX 03:27 JFK 06:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86