2012-05-30 60 views
5

例如假设我有这个类:有没有办法使用EasyMock部分模拟对象?

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子做这样的事情对我来说。但是如果我不必这样做,我不想这样做,因为它很乏味,即应该是自动化的。

回答

2

我想你可以使用EasyMock扩展库来做到这一点。你可以在这里找到一个简单的例子Partial Mocking

+0

谢谢您创建部分模拟!不幸的是,你似乎需要Junit 4才能使用classextensions :(:http://easymock.org/EasyMock2_2_ClassExtension_Documentation.html我想这意味着Junit 3用户运气不好。 – allyourcode

+0

Ohh ...这是一个很好的信息我也是......我对你的案例有一个想法...但它并没有使用简单的模拟,而是通过覆盖这些方法来创建嘲笑,并从扩展的Mock类返回模拟'Bar'对象。 – raddykrish

+2

从EasyMock 3.1开始,ClassExtensions库已被弃用,部分模拟已被移植到EasyMock本身。这说明它可以与JUnit 3一起使用,所以你可能会很幸运:http://easymock.org/EasyMock3_1_Documentation.html – DoctorRuss

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

} 
+0

但是不写FooSpy是有点意思的。 – allyourcode

+0

这很重要,除非你不能使用classextensions而受到阻碍 - 所以你没有一个框架来创建为你吃了你的间谍。不过,根据@ DoctorRuss的评论,你看起来可能很幸运。 – jhericks

2

的OP出现(?)暗示子类比某种方式比部分嘲讽更困难或更乏味。我建议值得重新考虑。

例如,在测试类:

Foo dummyFoo = new Foo() { 
     @Override public Bar b() { return new Bar(); } 
    }; 

做什么的OP状态,似乎简单,不易出现其他问题(忘记回放/确认/等),比使用EasyMock的。

+1

我不知道你可以在Java中做到这一点!我猜这是在1.4之后出来的?无论如何,你可以用这个来创建一个模拟,类似于jhericks的建议吗?如果是这样,那很酷,因为你不需要创建一个全新的(子)类来调用未经测试的方法的模拟。 – allyourcode

9

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

EasyMock.createMockBuilder(class).addMockedMethod("MethodName").createMock(); 
相关问题