当前位置: 首页 > 知识库问答 >
问题:

模拟测试类不直接使用的autowired spring依赖项(接口

陆烨烁
2023-03-14

问题(简而言之)-我如何模拟一个在我的JUnit中没有直接引用的spring依赖项。

public interface ServiceA{
    void invoke();
    ...10 more methods
}

@Service
public class ServiceAImpl implements ServiceA{
    @Autowired
    private ServiceB serviceB; 

    @Autowired
    private ServiceC serviceC;

    @Autowired
    private DAOA daoA;

    @Autowired
    private DAOB daoB;

    @Override
    public void invoke(arg1, arg2){
        // use above dependencies to do something
        serviceB.sendEmail(args);
    }
}
public interface ServiceB{
    void sendEmail();
    ...10 more methods
}

@Service
public class ServiceBImpl implements ServiceB{
    @Autowired
    private EmailUtil emailUtil;

    @Override
    public void sendEmail(args){
    emailUtil.sendEmail(args);
}

值得注意的是sendEmail方法返回void。

@Component
publIt'sclass EmailUtil{
    @Autowired
    private JavaMailSenderImpl javaMailSenderImpl;

    public void sendEmail(args){
    // send email using spring & other APIs
    }
}

我的集成测试JUnit如下所示。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/test-context.xml" })
public class ServiceIT{
    @Autowired
    private ServiceA serviceA;

    @Test
    public void testA(){
    // prepare data mock in H2 DB
    serviceA.invoke(arg1, arg2);
    // assertions
    }
}

问题(长)-Am使用H2作为模拟数据库,所以我的DAO调用可以(需要)发挥作用。我想模拟其他的第三方集成,比如serviceB中的emailutil.sendeMail调用,这样就不会发送电子邮件。由于在我的JUnit中使用的是serviceA,我的理解是,我需要创建EmailUtil的@mock,并将@injectmocks创建到ServiceB中,也就是@injectmocks创建到serviceA中。当我这样做时,Mockito会抛出错误,表示ServiceB是一个接口。创建ServiceA、ServiceB的模拟对象可能不是一个很好的选择,因为那样我可能不得不存根/模拟太多的行为。我想要在这些类中执行实际的逻辑,应该只对sendEmail方法进行模拟。

  1. 这是一个常见问题吗?
  2. 如何解决此问题?
  3. 这段代码的设计是否存在问题(即使用接口和自动连接所有内容),从而使测试/模拟变得困难。如果是,那么有什么更好的方法来实现?

Spring-4.0.3.发行版,JUnit-4.12,mockito-core-1.10.19

共有1个答案

斜俊
2023-03-14

在测试类ServiceIT中使用@mockbean模拟emailutil

可用于将模拟添加到Spring ApplicationContext的注释。可以用作类级注释,也可以用于@Configuration类或与SpringRunner一起运行的测试类中的字段。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/test-context.xml" })
public class ServiceIT{
@Autowired
private ServiceA serviceA;

@MockBean
private EmailUtil emailUtil;

@Test
public void testA(){
// prepare data mock in H2 DB

//given(this.emailUtil.sendEmail(ArgumentMatchers.any()).willReturn( custom object);
serviceA.invoke(arg1, arg2);
// assertions
     }
 }
 类似资料:
  • 问题:Maven在我的测试中找不到一些依赖项 在我的pom中是这样导入的。xml: 我已经试过了: mvn测试编译 使Intellij缓存无效 重启Intellij 清除. m2并重建项目

  • 问题内容: 我在一个模块中有一个测试类,该模块在其依赖项模块之一中扩展了另一个测试类。如何将依赖项的测试代码导入到依赖模块的测试范围中? 首先,我有两个模块,“ module-one”是对“ module-two”的依赖。是的子类。 但是构建失败了,因为没有将“模块一”的测试代码导入到“模块二”中,而只是将其导入到主代码中。 问题答案: 通常,除了常规的modulename.jar文件之外,还可以

  • 我有一个多模块maven项目,包含三个模块、和 Core具有以下依赖项定义 我已经为所有三个模块添加了Java9定义,的如下所示: 但是,我不知道如何让的测试类能够在测试执行期间看到类。当尝试测试运行时,找不到类。 如果向的添加需要My.Project.TestUtils;的: 然后在编译时,我得到一个错误,即找不到模块(大概是因为它只是作为测试依赖项引入的)。 在Java9模块化的世界中,如何处

  • 在阅读dagger 2的文档时,我找不到一种简单的方法来在构建测试应用时提供依赖项。我找到的唯一线索是: 匕首2不支持覆盖。覆盖简单测试假货的模块可以创建模块的子类来模拟该行为。应该分解使用覆盖并依赖依赖依赖项注入的模块,以便将被覆盖的模块表示为两个模块之间的选择。 我不明白我将如何在Android上设置这样的配置,任何人都可以解释吗?