有没有办法使用EasyMock部分模拟对象?

时间:2012-05-30 22:39:34

标签: java testing mocking easymock

E.g。假设我有这个课程:

public class Foo Implements Fooable {
  public void a() {
    // does some stuff
    bar = b();
    // moar coadz
  }
  public Bar b() {
    // blah
  }
  // ...
}

我想测试Foo.a。我想模仿Foo.b,因为我正在单独测试该方法。我想象的是这样的:

public class FooTest extends TestCase {
  public void testA() {
    Fooable foo = createPartialMock(
      Fooable.class,  // like with createMock
      Foo  // class where non-mocked method implementations live
    );

    // Foo's implementation of b is not used.
    // Rather, it is replaced with a dummy implementation
    // that records calls that are supposed to be made;
    // and returns a hard coded value (i.e. new Bar()).
    expect(foo.b()).andReturn(new Bar());

    // The rest is the same as with createMock:
    //   1. Stop recording expected calls.
    //   2. Run code under test.
    //   3. Verify that recorded calls were made.
    replay(foo);
    foo.a();
    verify(foo);
  }
}

我知道我可以编写自己的Foo子类来为我做这类事情。但如果我不需要,我不想这样做,因为它很乏味,即应该是自动化的。

4 个答案:

答案 0 :(得分:13)

在EasyMock 3.0+中,您可以使用mockbuilder

创建部分模拟
EasyMock.createMockBuilder(class).addMockedMethod("MethodName").createMock();

答案 1 :(得分:2)

我想你可以使用EasyMock扩展库来做到这一点。您可以在此Partial Mocking

中找到一个简单的示例

答案 2 :(得分:2)

OP出现(?)表明子类化比部分模拟更难或更乏味。我建议值得重新考虑一下。

例如,在测试类中:

  Foo dummyFoo = new Foo() {
      @Override public Bar b() { return new Bar(); }
   };
与使用EasyMock相比,

执行OP所说的,看起来更简单,更不容易出现其他问题(忘记重放/验证/等)。

答案 3 :(得分:1)

我会找到一种升级到JUnit 4的方法,并使用classextensions。 (实际上,我会使用Mockito而不是EasyMock,但是不要重写整个测试套件。)如果你不能,那么你可以随时创建自己的间谍:

public class FooTest extends TestCase {
    public static class FooSpy extends Foo {
        private final Fooable mockFoo;

        FooSpy(Fooable mockFoo) {
            this.mockFoo = mockFoo;
        }

        public Bar b() {
            return mockFoo.b();
        }
    }

    public void testA() {
        Fooable mockFoo = createMock(Foo.class);
        Fooable fooSpy = new FooSpy(mockFoo);

        // Foo's implementation of b is not used.
        // Rather, it is replaced with a dummy implementation
        // that records calls that are supposed to be made;
        // and returns a hard coded value (i.e. new Bar()).
        expect(mockFoo.b()).andReturn(new Bar());

        // The rest is the same as with createMock:
        // 1. Stop recording expected calls.
        // 2. Run code under test.
        // 3. Verify that recorded calls were made.
        replay(mockFoo);
        foo.a();
        verify(foo);
    }

}