JMockIt:是否可以在同一个TestClass中模拟同一个类两次,以验证不同场景中的行为

时间:2012-05-15 02:29:31

标签: mocking jmockit

对于Mocked类的不同行为,我需要编写一个测试,在这里,可以验证类的行为。为了支持同一方法的多个行为,我们需要在同一个TestClass中多次模拟该类。

是否可以使用JMockIt?

这是我想要的一个例子。这是要测试的主要类及其测试:

public class MyClass {

    private Foo fooObj = null;

    public setfooObj(Foo obj) {
        fooObj = obj;
    }

    public boolean process() {
        // uses fooObj.getName() to process 
    }
}

public class MyClassTest {

    @MockClass(realClass = mypackage.Foo.class)
    public static class MockFoo {

        @Mock
        public static boolean getName() {
            return "test";
        }
    }

    @Test
    public void validateProcessing() {
        MyClass testObj = new MyClass();
        assertEquals(false, testObj.process);
    }
}

现在,我希望在testObj.process()返回不同值时验证MockFoo.getName()方法的行为。对于我的第一个断言,我想将其值用作“test”(由mocked函数返回),但对于以下的断言,我想检查不同的值。

2 个答案:

答案 0 :(得分:1)

这很容易解决,并且不需要两次模拟同一个类。要在不同的调用中从同一个模拟方法返回不同的值,只需记录两个(或更多)连续返回值,如果使用“Expectations API”;如果使用“Mockups API”,则在模拟方法中添加“Invocation inv”类型的第一个参数,然后使用“inv.getInvocationIndex()”来知道应该返回哪个值(不如其他选项好,但是有效)细)。

有关更多文档和示例,请查看JMockit项目站点,或完整分发中的“jmockit / www”目录。

答案 1 :(得分:0)

是的,您可以使用@Injectable注释而不是@Mocked,然后每个模拟将是一个单独的实例。您可以对这些实例执行不同的期望/验证。

来自the tutorial的示例:

@Test
public void concatenateInputStreams(
  @Injectable final InputStream input1,
  @Injectable final InputStream input2)
{
  new Expectations() {{
     input1.read(); returns(1, 2, -1);
     input2.read(); returns(3, -1);
  }};

  InputStream concatenatedInput = new ConcatenatingInputStream(input1, input2);
  byte[] buf = new byte[3];
  concatenatedInput.read(buf);

  assertArrayEquals(new byte[] {1, 2, 3}, buf);
}