2012-05-30 59 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(); 
相關問題