public void sendMail() {
/* I have simplified the method for here */
Transport t;
t.send();
}
当我为此编写单元测试时,由于我不想实际发送邮件,所以我想模拟Transport
课程。有可能吗?如果可以,该怎么做?
public void sendMail() {
/* I have simplified the method for here */
Transport t;
t.send();
}
当我为此编写单元测试时,由于我不想实际发送邮件,所以我想模拟Transport
课程。有可能吗?如果可以,该怎么做?
除非你真的想使用 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 代码以来已经有一段时间了。希望没有太多错误。另外,你可能会比我更好地命名类。)
您可以尝试使用 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);
}
}
'cglib' 可能适合。
使用“Enhancer”代理“Transport”类。为了不实际发送邮件,您需要向“Enhancer”传递一个“MethodInterceptor”,它不会调用超类中的“send()”方法。
这是一个无论如何获得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(我开发的)。