Java 如何在 Spring 上下文中注入 Mock

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19808326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:21:22  来源:igfitidea点击:

How to inject a Mock in a Spring Context

javaspringdependency-injectionmockingmockito

提问by Mr.Eddart

I have a test that is using some Spring contexts. In these contexts, a number of beans are declared. I want the test to use the actual implementation of the beans of the contexts, EXCEPT for one of them, for which I want to use a MOCK.

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

I tried to make the Test a Configuration component (with @Configuration annotation), but the XML seems to take priority over the @Bean annotation, so it doesn't work, this way:

我试图使 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; }

    .....

I know that i can define the Mocks in XML, but for that I would need an extra XML file for each test in which I wish to do this. I want to avoid this complexity.

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

Is there a way to inject a bean (like a mock) in a context apart than through XML?

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

Thank you!

谢谢!

采纳答案by Mr.Eddart

It is indeed a duplicate of

它确实是一个副本

Injecting Mockito mocks into a Spring bean

将 Mockito 模拟注入 Spring bean

The Springockito-annotation is exactly what I was looking for

Springockito 注释正是我要找的

https://bitbucket.org/kubek2k/springockito/wiki/springockito-annotations

https://bitbucket.org/kubek2k/springockito/wiki/springockito-annotations

回答by vikingsteve

Yes, you are on the right track, putting a mock @Beanin a @Configurationclass is one approach, and I'll describe my experience:

是的,您走在正确的轨道上,@Bean@Configuration课堂上进行模拟是一种方法,我将描述我的经验:

The trick is that you need to use a different set of .xml files purely for testing which exclude the live versions of those beans.

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

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

And the "-test-xml" files go in src/test/resources.

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

At least that was my experience in doing the same thing. Maybe there is some way to "override" the beans with the mock versions, but as yet I am not aware of it.

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

I also chose to put the mocks (I had 5 of them) all together in an own configuration:

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

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

Another interesting part of this problem is the common usage of initMocks(this);in the @Beforemethod of your test class.

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

If the mocks are being used in other places (and they are, that's why you are wiring them up...) then initMocks(this)will blow them away between tests (not literally - just that new mocks will be created and any other mocks wired up in other objects will be "lost").

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

The solution to this was to call mockito's reset(mockObject)in the @Beforemethod before each test. The same mocks are reset (all the when's and interactions), without creating new mocks.

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

Note that the Mockito docs for resetsay very sternly that this method should not commonly be used, except in the context of mocks being applied via dependency injection, as we are indeed doing in this case :)

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

Have fun!

玩得开心!