如何注入相同接口的多个模拟

 gpik40799 发布于 2023-02-04 15:37

ServiceCaller我想测试的Java类(调用)有这个:

@Autowired @Qualifier(value="serviceA")
SomeService serviceA;

@Autowired @Qualifier(value="serviceB")
SomeService serviceB;

(有一种doWork()方法可以检查条件并调用A或B).

如何将每个服务的模拟注入适当的变量?

我的Junit有这个:

@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();

@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;

然而,当我运行我的测试以检查在正确条件下调用的服务A/B时,我得到空指针,因为没有注入模拟.

显然它是因为对同一个接口的多重依赖(SomeService).有没有办法在声明模拟服务时指定限定符?或者我是否需要为依赖项设置setter并设置旧的方式?

2 个回答
  • 为mocks serviceA和serviceB命名应该足够了.来自Mockito 文档:

    物业安装人员注入; mocks将首先按类型解析,然后,如果存在多个相同类型的属性,则通过属性名称和模拟名称的匹配来解析.

    在你的例子中:

    @InjectMocks ServiceCaller classUnderTest;
    
    @Mock SomeService serviceA;
    @Mock SomeService serviceB;
    

    请注意,使用@InjectMocks时无需手动创建类实例.

    不过我个人更喜欢使用构造函数注入依赖项.它可以更容易地在测试中注入模拟(只需用你的模拟调用构造函数 - 没有反射工具或@InjectMocks(这很有用,但隐藏了一些方面)).此外,使用TDD可以清楚地看到测试类需要哪些依赖项,IDE也可以生成构造函数存根.

    Spring Framework完全支持构造函数注入:

    @Bean
    public class ServiceCaller {
        private final SomeService serviceA;
        private final SomeService serviceB;
    
        @Autowired
        public ServiceCaller(@Qualifier("serviceA") SomeService serviceA,
                             @Qualifier("serviceB") SomeService serviceB) { ... }
    
        ...
    }
    

    可以使用以下代码测试此代码:

    @Mock SomeService serviceA;
    @Mock SomeService serviceB;
    
    //in a setup or test method
    ServiceCaller classUnderTest = new ServiceCaller(serviceA, serviceB); 
    

    2023-02-04 15:38 回答
  • 您可以使用"name"属性来定义您的实例,如下所示:

    @Mock(name="serviceA") SomeService serviceA;
    @Mock(name="serviceB") SomeService serviceB;
    

    2023-02-04 15:38 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有