Reputation: 158
I have a "Mailer" class in my project (which of course sends emails). For testing I want that every call of Mailer#send(String toAddress)
is replaced with Mailer#send("[email protected]")
.
So something like:
@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("[email protected]"));
try {
whenNew(Mailer.class).withAnyArguments().thenReturn(mailerMock);
} catch (Exception e) {
e.printStackTrace();
}
ClassCallingMailer someClass = new ClassCallingMailer();
assertTrue(someClass.methodSendingMail());
}
}
This code obviously is not working, but can this be achieved in some way? Maybe this is a completely wrong approach?
Thank you.
I'm not really sure how good this is but it's working:
// 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("[email protected]");
}
}
// 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());
}
}
Upvotes: 2
Views: 297
Reputation: 95
If you want to achieve only this behavior, I would suggest not to do by mocking.
You can extend your Mailer
class to have some TestMailer
in which you can do something like:
@Override
public void send(String toAddress){
super.send("[email protected]");
}
Basically you override the original send from the Mailer
and call it with the predefined address.
You can use this new subclass in your tests.
Upvotes: 1