spring - 在纠缠的 spring 上下文中进行单元测试

标签 spring junit mockito springmockito

假设遗留应用程序有 1500 个 spring.xml。我想为服务编写单元测试。我深陷依赖 hell 。我必须按原样接受应用程序,没有出路。

所以我们使用 spring-3.something 和 mockito-1.9,我想要测试服务的好方法。较新的代码大量使用 @Autowired 注释。

间接地,该服务使用了大约 25 个我实际上想在测试中使用的助手(工厂方法等),以及大约 25 个我对此测试不感兴趣的对象。

我目前尝试以上述方式设置上下文,但我对@Mock、@InjectMocks、@Autowired 的效果感到困惑。

我的测试如下。我需要帮助才能正确设置它。

问题:

  • @InjectMocks 的实际效果是什么?
  • 我如何(从技术上)决定哪些 Autowiring 的 bean 被真正使用,哪些被模拟替换?
  • 我知道,我滥用模拟来制造假货。有没有更简单的方法在单行中获取假货?
  • *请注意,我想了解这一点,因为我有大量此类服务...*

这是我的示例:

@ContextConfiguration(locations = {
    "classpath:/some/path/MainTestConfig.spring.xml"
})
@RunWith(SpringJUnit4ClassRunner.class)
public class SampleTest {

    // ***            Uninteresting Dependencies to be mocked        *** //
    @Mock Mock1 mock1;
    @Mock Mock2 mock2;

    /** Service under test */
    @Autowired
    SomeService service;

    // ***            Tightly coupled helpers to be used              *** //
    @Autowired Helper1 helper1
    @Autowired Helper2 helpr2

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(SampleTest.class);
    }

    @Test
    public void testSample() {

        // prepare dummy context
        SomeContext context = new Context();

        // define expected result
        int expectedValue = 42;

        //execute method under test, record result
        Result actualResult = service.execute(context);

        //make assertions on result
        assertTrue(actualResult.getSomething()==expectedValue);
    }

}

最佳答案

我想将其作为单独的答案发布,因为这应该更好地解决您关于@Mock、@Autowired 和@InjectMocks 的实际问题。

@Mock:当MockitoAnnotations.initMocks(this) 被调用。

@Autowired:标记应由 Spring 使用实现类/接口(interface)的 bean 分配的字段。

@InjectMocks:标记在调用 MockitoAnnoations.initMocks(this) 时应由 Mockito 创建的字段。它创建该类的一个实例并将 @Mock 注释的字段注入(inject)到该实例中。 (请参阅评论中对此声明的更正)。

分析:

@InjectMocks 与 Spring 上下文和 @Autowired 不兼容,因为 InjectMock 创建了它不使用 Spring 的类的新实例实例。

要执行您要查找的操作,您需要使用 Springockito . (延迟更新)Springockito 将允许您将模拟注入(inject)到您的 Spring 上下文中,从而将这些模拟用作 Autowired 候选对象。它允许模拟和 spy 。在测试的同一字段上使用 ReplaceWithMockAutowired 是一般做法(如 wiki 上的示例所示)。

关于spring - 在纠缠的 spring 上下文中进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16013077/

相关文章:

spring - 为什么 Spring WebFlux MockServerRequest 不允许空主体?

java - 类不包含用于 Autowiring 的匹配构造函数

java - 模拟抽象类中的新对象实例

java - 如何在我正在为其编写 junit 测试的方法中模拟方法调用

java - 关于Spring事务传播的问题

java - 在 Spring 中,@RequestParameter 注释不接受 defaultValue 参数的 boolean 值,它只适用于字符串 URL 请求参数

java - 自从 @SpringApplicationConfiguration、@WebIntegration 在 Spring Boot 框架中被弃用以来,正确的注释是什么?

java - Mockito @Mock 不使用构造函数注入(inject)正确注入(inject)命名模拟

java - 如何 JUnit 测试我的模拟方法是否使用我想要的参数(不仅仅是 id,而是深度相等匹配器)调用?

java - 如何在 Mockito 中多次 stub 异常