2

给定一个遗留应用程序有 1500 个 spring.xmls。我想为服务编写单元测试。我深陷依赖地狱。我必须按原样接受该应用程序,没有出路。

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

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

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

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

问题:

  • @InjectMocks 的实际效果是什么?
  • 我如何才能决定(技术上)真正使用哪些自动装配的 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);
    }

}
4

2 回答 2

4

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

@Mock: 这标记了一个在被调用时应该被创建为模拟(使用mock(MyClass.class))的字段MockitoAnnotations.initMocks(this)

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

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

分析:

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

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

于 2013-04-15T14:52:45.133 回答
2

第一个问题,你需要加载弹簧上下文做这个测试吗?通常,当我有 Spring 项目时,每个类都有一个不加载上下文文件的 UNIT 测试。我将有一个不同的 CONTEXT 测试来加载上下文文件并验证它是否正确加载。如果您正在进行真正的单元测试,我建议您不要加载上下文。如果被测类@Autowired用于分配依赖项(因此没有设置器),则使用 SpringReflectionTestUtils分配这些字段。

于 2013-04-15T12:19:11.260 回答