Skip to content

Instantly share code, notes, and snippets.

@virtix
Created February 23, 2011 14:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save virtix/840494 to your computer and use it in GitHub Desktop.
Save virtix/840494 to your computer and use it in GitHub Desktop.
Dependency example
package edu.gmu;
import java.util.List;
import org.apache.log4j.*;
public class Emailer {
public void sendEmail(List<Recipient> recipients, String message){
EmailService service = new EmailService();
service.connect();
for(Recipient recipient : recipients){
service.send( recipient, message );
}
service.close();
}
}
package edu.gmu;
import java.util.List;
import org.apache.log4j.*;
public class BetterEmailer {
/**
* Creates a real EmailService by default with the option of
* using a different one.
*
*/
EmailService service = new EmailService();
public void setEmailService(EmailService service) {
this.service = service;
}
public void sendEmail(List<Recipient> recipients, String message){
service.connect();
for(Recipient recipient : recipients){
service.send( recipient, message );
}
service.close();
}
}
package edu.gmu;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.*;
public class EmailerTest {
List<Recipient> recipients = Arrays.asList(
new Recipient("Ed One", "ed1@ed.com"),
new Recipient("Ed Two", "ed2@ed.com"),
new Recipient("Ed Three", "ed3@ed.com"),
new Recipient("Ed Four", "ed4@ed.com")
);
/**
* No mocks. (And not really much of a test)
*
* How would "you" test a method that returns void?
*
* */
@Test
public void shouldUseDefaultEmailer() {
Emailer emailer = new Emailer();
emailer.sendEmail(recipients, "Thank you for visiting teh internets!");
}
/**
* Using Improved BetterEmailer but has same effect.
*
* Still not a very good test.
*
* */
@Test
public void shouldUseBetterEmailer() {
BetterEmailer emailer = new BetterEmailer();
emailer.sendEmail(recipients, "Thank you for visiting teh internets!");
}
/**
* Inject mock into object under test. And verify calls. Much better test.
*
* */
@Test
public void handBuiltFakeSpamExample() {
BetterEmailer emailer = new BetterEmailer();
//Create an in-line fake object.
EmailService fakeService = new EmailService(){
@Override
public void connect(){
System.out.println("connecting fake.\n");
}
@Override
public void close(){
System.out.println("closing fake.\n");
}
@Override
public void send(Recipient recipient, String message){
System.out.print("Yeah, ya got here, " + recipient + "\n");
}
};
//Kills side effects, but now what?
emailer.setEmailService(fakeService);
//exercise object under test
emailer.sendEmail(recipients, "Thank you for visiting teh internets!");
}
/**
* Inject mock into object under test. And verify calls. Much better test.
*
* */
@Test
public void injectedMockSpamExample() {
BetterEmailer emailer = new BetterEmailer();
//Create a mock email service
EmailService mockService = mock(EmailService.class);
//Inject emailer with mock
//emailer.setEmailService( mockService );
emailer.setEmailService(mockService);
//exercise object under test
emailer.sendEmail(recipients, "Thank you for visiting teh internets!");
//Perform verifications
//Verify correct number of calls (intentionally out of order for demo)
verify(mockService, times(4)).send( any(Recipient.class), anyString() );
verify(mockService).close();
verify(mockService).connect();
//Verify number AND order
InOrder inOrder = inOrder(mockService);
inOrder.verify(mockService).connect();
inOrder.verify(mockService, times(4)).send( any(Recipient.class), anyString() );
inOrder.verify(mockService).close();
}
//Or can create inner class
class FakeEmailService extends EmailService {
@Override
public void connect(){}
@Override
public void close(){}
@Override
public void send(Recipient recipient, String message){
System.out.print("Yeah, ya got here, " + recipient + "\n");
}
}
}
package edu.gmu;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class EmailService {
Logger logger = Logger.getLogger(EmailService.class);
{
BasicConfigurator.configure();
}
public void connect() {
logger.info("connect()");
}
public void send(Recipient recipient, String message) {
logger.info("Spamming : " + recipient);
//Ideally would also handle exceptions ...
}
public void close() {
logger.info("close()");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment