如何在春季环境中注入模拟

我有一个测试,使用一些春季背景。在这些上下文中,声明了许多豆子。我希望测试使用上下文的bean的实际实现,除了其中一个,我想使用MOCK。

我试图使Test成为配置组件(带有@Configuration注释),但是XML似乎优先于@Bean注释,因此它不起作用,这样:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"context1.xml", "context2.xml", ...})
@Configuration
public class MyTest{

    @Inject
    private MyTargetBean target;

    private AnotherBean myMock = mock(AnotherBean.class);

    @Bean
    public AnotherBean myMock() { return myMock; }

    .....

我知道我可以用XML定义Mocks,但为此,我需要为我希望这样做的每个测试提供一个额外的XML文件。我想避免这种复杂性。

有没有办法在上下文中注入一个bean(如模拟),而不是通过XML?

谢谢!


答案 1

是的,你走在正确的轨道上,在课堂上放一个模拟是一种方法,我会描述我的经历:@Bean@Configuration

诀窍在于,您需要使用一组不同的.xml文件来纯粹用于测试,其中排除了这些bean的实时版本。

@ContextConfiguration(locations = {"context1-test.xml", "context2-test.xml", ...})

“-test-xml”文件进入 .src/test/resources

至少这是我做同样的事情的经验。也许有某种方法可以用模拟版本“覆盖”豆子,但到目前为止,我还没有意识到这一点。

我还选择将模拟(我有5个)放在一个单独的配置中:

@Configuration
public class MockServicesProvider {
     @Bean
     public AnotherBean myMock() { return mock(AnotherBean.class); }
}

这个问题的另一个有趣的部分是测试类的方法中的常见用法。initMocks(this);@Before

如果这些模拟在其他地方被使用(它们确实如此,这就是为什么你把它们连接起来......),那么它们将在测试之间被吹走(不是字面上的 - 只是将创建新的模拟,而连接在其他对象中的任何其他模型将被“丢失”)。initMocks(this)

解决这个问题的方法是在每次测试之前在方法中调用mojito。相同的模拟被重置(所有 's 和交互),而不创建新的模拟。reset(mockObject)@Beforewhen

请注意,Mockito文档非常严厉地说,除了在通过依赖关系注入应用模拟的上下文中,否则不应该通常使用此方法,因为在这种情况下我们确实在这样做:)reset

玩得愉快!


推荐