我的项目中有一个“Mailer”课程(当然会发送电子邮件)。对于测试,我希望Mailer#send(String toAddress)
的每次通话都替换为Mailer#send("mail@example.com")
。
类似于:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassCallingMailer.class})
public class TestClass {
@Test
public void testMethod() {
Mailer mailerMock = mock(Mailer.class);
// this is where the magic happens; replace any toAddress with fixed email address
when(mailerMock.send(any(String.class))).thenReturn(mailerMock.send("mail@example.com"));
try {
whenNew(Mailer.class).withAnyArguments().thenReturn(mailerMock);
} catch (Exception e) {
e.printStackTrace();
}
ClassCallingMailer someClass = new ClassCallingMailer();
assertTrue(someClass.methodSendingMail());
}
}
这段代码显然不起作用,但这可以通过某种方式实现吗? 也许这是一种完全错误的做法?
谢谢。
我不确定这有多好但是它有效:
// ClassCallingMailer (no changes, just for completeness)
public class ClassCallingMailer {
public boolean methodSendingMail() {
Mailer mail = new Mailer();
return mail.send(someEmailAddress);
}
}
// TestMailer (new class)
public class TestMailer extends Mailer {
// add all constructors from Mailer
@Override
public boolean send(String to) {
return super.send("mail@example.com");
}
}
// TestClass (with changes)
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassCallingMailer.class})
public class TestClass {
@Test
public void testMethod() {
// changed mock to spy and replaced Mailer with TestMailer
Mailer mailerMock = spy(TestMailer.class);
// removed "when(...).thenReturn(...)"
try {
whenNew(Mailer.class).withAnyArguments().thenReturn(mailerMock);
} catch (Exception e) {
e.printStackTrace();
}
ClassCallingMailer someClass = new ClassCallingMailer();
assertTrue(someClass.methodSendingMail());
}
}
答案 0 :(得分:1)
如果你只想实现这种行为,我建议不要通过嘲笑来做。
您可以将Mailer
课程扩展为一些TestMailer
,其中您可以执行以下操作:
@Override
public void send(String toAddress){
super.send("mail@example.com");
}
基本上,您覆盖Mailer
的原始发送,并使用预定义的地址进行调用。
您可以在测试中使用这个新的子类。