使用EasyMock进行单元测试时发生意外的方法调用

时间:2011-09-15 11:24:42

标签: java unit-testing easymock

我正在使用UnitilsJUnit4和EasyMock在我的代码中测试邮件功能。

我的代码是这样的..

public void prepare(MimeMessage mimeMessage) {
// some code ..
MimeMessageHelper message = new MimeMessageHelper( mimeMessage, true );
// some mail settings ..

}

当我测试方法prepare时,它给出了以下异常..但下面显示的方法来自Spring框架类。

java.lang.AssertionError: 
  Unexpected method call setContent(javax.mail.internet.MimeMultipart@6e616e61):
    setContent(javax.mail.internet.MimeMultipart@2dda2dda): expected: 1, actual: 0
    at $javax.mail.internet.MimeMessage$$EnhancerByCGLIB$$614de43f.setContent(<generated>)
    at org.springframework.mail.javamail.MimeMessageHelper.createMimeMultiparts(MimeMessageHelper.java:344)
    at org.springframework.mail.javamail.MimeMessageHelper.<init>(MimeMessageHelper.java:290)
    at org.springframework.mail.javamail.MimeMessageHelper.<init>(MimeMessageHelper.java:247)
    at org.springframework.mail.javamail.MimeMessageHelper.<init>(MimeMessageHelper.java:226)

请帮我解决上述问题..如何测试我的方法?

3 个答案:

答案 0 :(得分:2)

我知道这是很久以前写的,但我刚刚遇到了同样的问题。

如果您可以以某种形式模拟MimeMessageHelper,则可以轻松地测试代码。我这样做是通过创建一个简单地提供MimeMessageHelper类的接口并将其作为依赖项添加到我正在测试的类中。

<强>接口

public interface MimeMessageHelperProvider {
    MimeMessageHelper getMimeMessageHelper(MimeMessage mimeMessage);
}

<强>实施

public class MimeMessageHelperProviderImpl implements MimeMessageHelperProvider {
    @Override
    public MimeMessageHelper getMimeMessageHelper(MimeMessage mimeMessage) {
        return new MimeMessageHelper(mimeMessage);
    }
}

现在您可以连接MimeMessageHelperProvider并简单地模拟该界面,让它返回您可以验证的实例。

答案 1 :(得分:1)

你似乎在嘲笑错误的东西。当你应该嘲笑Spring类时,你正在嘲笑Mail API,因为那是你直接与之交互的东西。你现在的方式是,你有效地测试Spring类和你自己的类,这不是你想要的。

答案 2 :(得分:1)

您需要模拟MimeMessageHelper。你不能注入它,因为它在构造函数中需要mimeMessage。所以要做到这一点,你需要像PowerMock这样的东西。

来自documentation

  
      
  1. 使用@RunWith(PowerMockRunner.class)注释   测试用例的类级别。
  2.   
  3. 使用@PrepareForTest(ClassThatCreatesTheNewInstance.class)   注释   测试用例的类级别。
  4.   
  5. 使用   PowerMock.createMock(NewInstanceClass.class)创建一个mock   宾语   应该构建的类(让我们称之为   mockObject)。
  6.   
  7. 使用   PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject)   至   期待一种新的类型对象的构造   NewInstanceClass.class,而是返回模拟对象。
  8.   
  9. 使用   PowerMock.replay(mockObject,NewInstanceClass.class)改变了   模拟对象和类到重放模式,或者使用   PowerMock.replayAll()方法。
  10.   
  11. 使用PowerMock.verify(mockObject,   NewInstanceClass.class)将模拟对象和类更改为   验证模式,或者使用PowerMock.verifyAll()方法。
  12.   

显然,我真的不知道你要测试的是什么,但你的测试看起来像是:

@RunWith(PowerMockRunner.class)
@PrepareForTest(MessagePreparer.class)
public class MessagePreparerTest {

  @Test
  public void testPrepare() {
    MimeMessage mockMessage = PowerMock.createMock(MimeMessage.class);
    MimeMessageHelper mockMessageHelper = PowerMock.createMock(MimeMessageHelper.class);
    PowerMock.expectNew(MimeMessageHelper.class, 
                        mockMessage, true).andReturn(mockMessageHelper);
    // ...set other expectations
    PowerMock.replay(mockMessage, mockMessageHelper, MimeMessageHelper.class);
    MessagePreparer messagePreparer = new MessagePreparer();
    messagePreparer.prepare(mockMessage);
    PowerMock.verify(mockMessage, mockMessageHelper, MimeMessageHelper.class);
  }
}