如何模拟代码中使用的类

时间:2013-08-02 03:14:23

标签: java unit-testing mockito

public void sendMail() {  
    /* I have simplified the method for here */
    Transport t;
    t.send();
}

当我为此编写单元测试时,因为我不想实际发送邮件,所以我想模拟Transport类。是否可能,如果可行,怎么做?

4 个答案:

答案 0 :(得分:0)

'cglib'可能适合。
使用'Enhancer'代理'Transport'类。为了不实际发送邮件,你需要将'Enhancer'传递给'MethodInterceptor',它不会在超类中调用'send()'方法。

答案 1 :(得分:0)

除非你真的想使用mockito,否则你可以很容易地手工制作你自己的测试双倍。

您可以做的是创建一个知道如何发送邮件的界面:

public interface TransportInterface {
    public void send(Message msg);
}

让邮件发送类使用此接口发送邮件:

public class MailSender {
    private TransportInterface transport;

    public MailSender(TransportInterface transport) {
        this.transport = transport;
    }

    public void sendMail(Message msg) {
        /* This is the method from your question */
        this.transport.send(msg);
    }
}

在制作中,您使用实际发送邮件的TransportInterface实现:

public class TransportAdapter implements TransportInterface {
    private Transport transport; // Created elsewhere...

    public void sendMail(Message msg) {
        transport.send(msg);
    }
}

在您的测试代码中,您可以使用假的:

public class TransportFake implements TransportInterface {
    public void sendMail(Message msg) {
        // I don't send the mail!
    }
}

(自从我编写java以来​​已经有一段时间了。希望错误不会太多。而且,你可以比我更好地命名这些类。)

答案 2 :(得分:0)

您可以尝试使用Mockito库: 这是示例代码:

import org.mockito.Mock;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class YourTestClass{
@Mock
Transport t;

@Test
public void someTest(){
t = Mockito.mock(Transport .class);
    Mockito.when(t.send()).thenReturn(true);
}
}

答案 3 :(得分:0)

这是一个解决方案,无论如何获取Transport t对象:

@Test
public sendMail(
    // Mocks all current and future Transport instances, 
    // including those belonging to subclasses (if any).
    @Capturing final Transport t)
{
    new SUT().sendMail();

    // Verifies that the t.send() method was called:
    new Verifications() {{ t.send(); }};
}

上面使用的模拟API是JMockit(我开发)。