2010-06-09 15 views
24

我使用EasyMock(版本2.4)和TestNG編寫UnitTest。java.lang.IllegalStateException:上述方法調用缺少的行爲定義getMessage(「title」)

我有以下場景,我無法改變類層次結構的定義方式。

我在測試擴展ClassA的ClassB。

ClassB的這個樣子

public class ClassB extends ClassA { 

    public ClassB() 
    { 
     super("title"); 
    } 

    @Override 
    public String getDisplayName() 
    { 
     return ClientMessages.getMessages("ClassB.title"); 
    } 

} 

ClassA的代碼

public abstract class ClassA { 
    private String title; 

    public ClassA(String title) 
    { 
     this.title = ClientMessages.getMessages(title); 
    } 

    public String getDisplayName() 
    { 
     return this.title; 
    } 
} 

ClientMessages類代碼

public class ClientMessages { 
    private static MessageResourse messageResourse; 

    public ClientMessages(MessageResourse messageResourse) 
    { 
     this.messageResourse = messageResourse; 
    } 
    public static String getMessages(String code) 
    { 
     return messageResourse.getMessage(code); 

    } 
} 

MessageResourse類代碼

public class MessageResourse { 
    public String getMessage(String code) 
    { 
     return code; 
    } 
} 

測試ClassB的

import static org.easymock.classextension.EasyMock.createMock; 

import org.easymock.classextension.EasyMock; 
import org.testng.Assert; 
import org.testng.annotations.Test; 

public class ClassBTest 
{ 
    private MessageResourse mockMessageResourse = createMock(MessageResourse.class); 
    private ClassB classToTest; 
    private ClientMessages clientMessages; 


    @Test 
    public void testGetDisplayName() 
    { 

    EasyMock.expect(mockMessageResourse.getMessage("ClassB.title")).andReturn("someTitle"); 

     clientMessages = new ClientMessages(mockMessageResourse); 

     classToTest = new ClassB(); 

     Assert.assertEquals("someTitle" , classToTest.getDisplayName()); 
     EasyMock.replay(mockMessageResourse); 
    } 
} 

當我運行這個這個測試我發現了以下情況例外:

java.lang.IllegalStateException :缺少上述方法調用getMessage的行爲定義(「標題」)

在調試我發現是,它不考慮模擬方法調用 mockMessageResourse.getMessage(「ClassB.title」),因爲它已經從construtor(ClassB的對象創建)調用。

任何人都可以幫助我在這種情況下如何測試。

謝謝。

回答

40

在調用測試方法之前,您需要調用EasyMock.replay(mock)。在調用測試方法後,您可以撥打EasyMock.verify(mock)來驗證模擬被調用。

接下來你需要添加另一個expect呼叫與「標題」參數,因爲你稱它兩次。

代碼:

EasyMock.expect(mockMessageResourse.getMessage("title")).andReturn("title");  
EasyMock.expect(mockMessageResourse.getMessage("ClassB.title")).andReturn("someTitle"); 
EasyMock.replay(mockMessageResourse); 
clientMessages = new ClientMessages(mockMessageResourse); 

classToTest = new ClassB(); 

Assert.assertEquals("someTitle" , classToTest.getDisplayName()); 
EasyMock.verify(mockMessageResourse); 
0

這可能有各種原因(someMock是你在這個答案模擬對象的名稱)。 在一個方面,它可以是您需要通過

expect(someMock.someMethod(anyObject()).andReturn("some-object"); 

期望呼叫像Reda's answer。 也可能是您在使用模擬前忘記呼叫replay(someMock),如在Julien Rentrop's answer中看到的那樣。

這裏沒有提到的可能的最後一件事是,您在測試之前在其他地方使用了模擬,並忘記通過reset(someMock)重置模擬。

如果你有多個單元測試這樣就會發生這種情況:

private Object a = EasyMock.createMock(Object.class); 

@Test 
public void testA() throws Exception { 
    expect(a.someThing()).andReturn("hello"); 
    replay(a); 

    // some test code and assertions etc. here 
    verify(a); 
} 

@Test 
public void testB() throws Exception { 
    expect(a.someThing()).andReturn("hello"); 
    replay(a); 

    // some test code and assertions etc. here 
    verify(a); 
} 

這將在與IllegalStateException異常一次測試失敗,因爲模擬一個沒有在接下來的測試中使用之前復位。要解決它,您可以執行以下操作:

private Object a = EasyMock.createMock(Object.class); 

@Test 
public void testA() throws Exception { 
    expect(a.someThing()).andReturn("hello"); 
    replay(a); 

    // some test code and assertions etc. here 
    verify(a); 
} 

@Test 
public void testB() throws Exception { 
    expect(a.someThing()).andReturn("hello"); 
    replay(a); 

    // some test code and assertions etc. here 
    verify(a); 
} 

@After 
public void tearDown() throws Exception { 
    reset(a); // reset the mock after each test 
} 
相關問題