【问题标题】:@Autowired inside SpringRunner SpringBootTest Unit Test Cases@Autowired 在 SpringRunner SpringBootTest 单元测试用例中
【发布时间】:2018-02-07 02:30:58
【问题描述】:

我们的 Spring Boot REST API 目前有一个相当大的单元测试存储库。单元测试将常见的可重用测试代码重构为带有@Component 注释的TestUtil 类。

看来SpringRunner 单元测试用例只能找到@Autowired TestUtil 类,如果它们作为@SpringBootTest 注释的类参数的一部分导入的话。

另外,TestUtil 类中的所有@Autowired 变量也需要在@SpringBootTest 注解的classes 参数中导入。

由于我们有大约 30 个单元测试用例类,并且每个类需要在 @SpringBootTest 注释中导入大约 40 个其他类,可以想象这变得多么难以维护。

如果没有将类作为@SpringBootTest classes 参数的一部分导入,则会引发以下错误

org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“com.company.FeeTest”的 bean 时出错:不满意 通过字段“accountTestUtils”表示的依赖关系;嵌套的 例外是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 'com.company.accountTestUtils' 类型的合格 bean 可用: 预计至少有 1 个 bean 有资格作为 autowire 候选者。 依赖注解: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

有没有人知道在单元测试用例中使用@Autowired 注释而不必在@SpringBootTest 注释中显式导入它们的更好方法?

下面是一个代码示例

FeeTest.java

package com.company;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
        AccountTestUtils.class,
        ... need to list any @Autowired component in AccountTestUtils
})
public class FeeTest {
    @Autowired
    private AccountTestUtils accountTestUtils;

    @Test
    public void basicFeeTestExpectSuccess() {
       accountTestUtils.createAccount();
       ...
    }
}

TransferTest.java

package com.company;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
        AccountTestUtils.class,
        ... need to list any @Autowired component in AccountTestUtils
})
public class TransferTest {
    @Autowired
    private AccountTestUtils accountTestUtils;

    @Test
    public void basicTransferTestExpectSuccess() {
       accountTestUtils.createAccount();
       ...
    }
}

AccountTestUtils.java

package com.company;

@Component
public class AccountTestUtils {
    @Autowired
    private IService1 someService1;

    @Autowired
    private IService2 someService2;

    @Autowired
    private SomeRepository someRepository1;

    public void createAccount() {
      someService1.doSomething();
      someService2.doSomething();
        someRepository2.doSomething();
    }
}    

我们的包结构是常见的maven结构

/src
    /main
        /java
        /resources
    /test
        /java
        /resources

【问题讨论】:

  • 找到解决方案了吗?
  • 没有,很遗憾没有
  • 当我从基于 Eclipse + Maven 的环境切换到 Intelij + Gradle 时发生此错误。重新启动 IDE 并重建后,我的错误消失了。

标签: java unit-testing autowired spring-boot-test


【解决方案1】:

从TransferTest.java类的观点说起。

该类测试 AccountUtilsTest 类。因此,只需将 AccountUtilTest 类的依赖项提供给 TransferTest.Mock 每个自动连接并在 AccountUtilsTest 中使用的依赖项。

例如:

package com.company;

@RunWith(SpringRunner.class)
public class TransferTest {

    @Mock
    IService1 someService1Mock;

    @Mock
    IService2 someService2Mock


    @InjectMocks
    private AccountTestUtils accountTestUtils;

    @Test
    public void basicTransferTestExpectSuccess() {
       accountTestUtils.createAccount();
       ...
    }
}

【讨论】:

    猜你喜欢
    • 2020-03-13
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2019-11-04
    • 2018-06-15
    • 2019-11-17
    • 2019-07-31
    相关资源
    最近更新 更多