Created
February 23, 2011 14:38
-
-
Save virtix/840494 to your computer and use it in GitHub Desktop.
Dependency example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", "[email protected]"), | |
new Recipient("Ed Two", "[email protected]"), | |
new Recipient("Ed Three", "[email protected]"), | |
new Recipient("Ed Four", "[email protected]") | |
); | |
/** | |
* 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"); | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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