简体   繁体   English

如何模拟Springockito模拟的行为?

[英]How to mock behavior for Springockito mocks?

If I create a mock in my spring context file using Springockito as described here , how do I mock some behavior for it? 如果我在使用Springockito描述我的Spring上下文文件创建一个模拟在这里 ,我怎么嘲笑为它的一些行为?

What I'm trying to do: 我正在尝试做什么:

  1. ClassA is being tested. ClassA正在测试中。
  2. ClassB is autowired in ClassA. ClassB在ClassA中自动装配。
  3. ClassB is being mocked with Springockito. ClassB正在被Springockito嘲笑。
  4. ClassA needs ClassB to do something in its PostConstruct. ClassA需要ClassB在其PostConstruct中做一些事情。
  5. I need to mock ClassB to do that something, since it can't and shouldn't really do it. 我需要模拟ClassB才能做到这一点,因为它不能也不应该真的这样做。

Doing this is straight forward without using Springockito (using Mockito straight up), but I need to autowire these beans and use Spring in my tests. 在没有使用Springockito(直接使用Mockito)的情况下这样做是直截了当的,但我需要自动装配这些bean并在我的测试中使用Spring。 Any help is appreciated. 任何帮助表示赞赏。

Note that new springockito-annotations help to achieve the same goal without messing with xml context and extra helper classes: 请注意,新的springockito-annotations有助于实现相同的目标,而不会弄乱xml上下文和额外的帮助程序类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:test-config.xml")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MemoAutoTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private ClassA classA;
    @Autowired @ReplaceWithMock
    private ClassB classB;

    @Test
    public void testClassA() {
        // stub B 
        when(classB.foo()).thenReturn(true);
        when(classB.bar()).thenReturn(42);

        // test A
    }

}

This would cause ClassB to be replaced with mock at main application context initialization. 这将导致在主应用程序上下文初始化时用mock替换ClassB。

I'm not familiar with Springockito, but it looks interesting for some narrow cases - namely integration testing with mocking just a bit. 我对Springockito并不熟悉,但对于一些狭隘的案例来说它看起来很有趣 - 即集成测试只是一点点嘲弄。

Anyway, it looks like for a straightforward use case you extend AbstractJUnit4SpringContextTests , you could also autowire ClassB in your test just like you do in ClassA. 无论如何,对于一个简单的用例,你可以扩展AbstractJUnit4SpringContextTests ,你也可以在你的测试中自动装配ClassB,就像在ClassA中一样。 Then you could define your expected behavior for ClassB in your setup method. 然后,您可以在setup方法中定义ClassB的预期行为。

But I think that you need to set up some behavior for the ClassB bean before you get access to it in your setup method. 但我认为您需要在设置方法中访问它之前为ClassB bean设置一些行为。 In that case, you may need another bean to set up ClassB to do the expected behavior. 在这种情况下,您可能需要另一个bean来设置ClassB以执行预期的行为。 So your testContext.xml would have something like this in it: 所以你的testContext.xml会有这样的东西:

<bean id="classA" class="com.jarvis.ClassA" depends-on="classBMockSetter" />
<mockito:mock id="classB" class="com.jarvis.ClassB" />
<bean id="classBMockSetter" class="com.jarvis.test.ClassBMockSetter">
  <property name="classB" ref="classB" />
</bean>

The ClassBMockSetter would look something like: ClassBMockSetter看起来像:

public class ClassBMockSetter {
  private ClassB classB;
  public void setClassB(ClassB classB) {
    this.classB = classB;
    given(classB.foo()).willReturn(true);
    given(classB.bar()).willReturn(42);
  }
}

I think that would work, but at that point, isn't it easier to just hand-code your mock ClassB? 我认为这样可行,但在那时,手动编写你的模拟ClassB是不是更容易?

What is worked for me is using @InjectMocks notation. 对我有用的是使用@InjectMocks表示法。 (See https://bitbucket.org/kubek2k/springockito/wiki/Home ) (见https://bitbucket.org/kubek2k/springockito/wiki/Home

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:test-config.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class MemoAutoTest extends AbstractJUnit4SpringContextTests { @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(loader = SpringockitoContextLoader.class,locations =“classpath:test-config.xml”)@ DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)public class MemoAutoTest extends AbstractJUnit4SpringContextTests {

@Autowired
private ClassA classA;
@Autowired @InjectMocks
private ClassB classB;

@Test
public void testClassA() {
    // stub B 
    when(classB.foo()).thenReturn(true);
    when(classB.bar()).thenReturn(42);

    // test A
    classA.doSomethingThatInternallyCallClassBFoo();
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM