在纠缠的春天环境中进行单元测试

时间:2013-04-15 10:36:37

标签: spring junit mockito springmockito

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

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

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

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

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

问题:

  • @InjectMocks的实际效果是什么?
  • 我如何(技术上)决定哪些自动装豆真正使用,哪些被模拟取代?
  • 我知道,我在滥用嘲笑来制造假货。是否有更简单的方法来获得单行假货?
  • * 请注意我想理解这一点,因为我有很多此类服务...... *

这是我的样本:

@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);
    }

}

2 个答案:

答案 0 :(得分:4)

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

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

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

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

分析:

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

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

答案 1 :(得分:2)

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