3

如果我使用 Springockito 在我的 spring 上下文文件中创建一个模拟,如此处所述我如何模拟它的一些行为?

我正在尝试做的事情:

  1. A 类正在测试中。
  2. ClassB 在 ClassA 中自动装配。
  3. ClassB 被 Springockito 嘲笑。
  4. ClassA 需要 ClassB 在其 PostConstruct 中做某事。
  5. 我需要模拟 ClassB 来做这件事,因为它不能也不应该真的这样做。

在不使用 Springockito(直接使用 Mockito)的情况下这样做是直接的,但我需要自动装配这些 bean 并在我的测试中使用 Spring。任何帮助表示赞赏。

4

3 回答 3

3

请注意,新的 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
    }

}

这将导致 ClassB 在主应用程序上下文初始化时被替换为模拟。

于 2013-10-21T14:33:43.350 回答
2

我对 Springockito 不熟悉,但对于一些狭窄的案例来说它看起来很有趣——即带有一点模拟的集成测试。

无论如何,对于扩展AbstractJUnit4SpringContextTests的简单用例,您也可以像在 ClassA 中一样在测试中自动装配 ClassB。然后,您可以在设置方法中定义 ClassB 的预期行为。

但我认为您需要为 ClassB bean 设置一些行为,然后才能在 setup 方法中访问它。在这种情况下,您可能需要另一个 bean 来设置 ClassB 以执行预期的行为。所以你的 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>

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

我认为这会奏效,但到那时,手动编写模拟 ClassB 不是更容易吗?

于 2012-06-21T04:20:35.093 回答
0

对我有用的是使用@InjectMocks表示法。(见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) 公共类 MemoAutoTest 扩展 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();
}

}

于 2014-12-03T09:19:08.230 回答