【问题标题】:How to inject a Mock in a Spring Context [duplicate]如何在 Spring 上下文中注入 Mock [重复]
【发布时间】:2013-11-17 11:14:30
【问题描述】:

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

我尝试将 Test 设为 Configuration 组件(带有 @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 文件用于我希望在其中执行此操作的每个测试。我想避免这种复杂性。

除了通过 XML 之外,有没有办法在上下文中注入 bean(如模拟)?

谢谢!

【问题讨论】:

    标签: java spring dependency-injection mocking mockito


    【解决方案1】:

    是的,你在正确的轨道上,将模拟 @Bean 放在 @Configuration 类中是一种方法,我将描述我的经验:

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

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

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

    至少这是我做同样事情的经验。也许有一些方法可以用模拟版本“覆盖”bean,但目前我还不知道。

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

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

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

    如果模拟正在其他地方使用(它们是,这就是你将它们连接起来的原因......)然后initMocks(this) 将在测试之间将它们吹走(不是字面意思 - 只是将创建新的模拟并连接在其他对象中的任何其他模拟都将“丢失”)。

    解决方案是在每次测试之前在 @Before 方法中调用 mockito 的 reset(mockObject)。重置相同的模拟(所有when 和交互),而不创建新模拟。

    请注意,reset 的 Mockito 文档非常严厉地表示,这种方法不应该被普遍使用,除非在通过依赖注入应用模拟的情况下,正如我们在这种情况下所做的那样 :)

    玩得开心!

    【讨论】:

      【解决方案2】:

      【讨论】:

      猜你喜欢
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 2013-07-01
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多