4.2. External Systems

While the WroxPizza sample doesn't interact with external systems, it is very common for web applications to need external systems such as email servers.

4.2.1. Email Servers

Although your WroxPizza application doesn't have any email implementation, you could easily imagine that when an order is placed an email confirmation is sent. This is a very common feature and has certain issues when it comes to testing the implementation.

Imagine your implementation has a controller which contains some logic and is required to send an alert via email. You then have an EmailService object which implements the INotificationService interface. The EmailService will communicate with your SMTP Server and send the email.

As described in Chapter 3, testing your higher level controller logic is very easy as you can simply use a mock object to verify the two are implemented as expected:

[TestFixture]
public class ControllerTests
{
   [Test]
   public void CanSendEmail()
   {
      var notification = new Notification {Text = "Test"};

      var mock = MockRepository.GenerateMock<INotificationService>();
      mock.Expect(i => i.SendNotification(notification)).Return(true);

      Controller controller = new Controller(mock);
      controller.SendAlert(notification);

      mock.VerifyAllExpectations();

}
}

However, the problem is testing your EmailService to verify that it works as expected; you need to actually connect to an SMTP Server. There are two major problems with this. First is the fact you need to set up and figure an SMTP Server. This has administration problems but also security concerns — as spammers gain access to the test server they can use it to spam people — not ideal. Secondly, you don't want emails being actually sent to people. The solution is to use a fake SMTP Server.

There are a few implementations of a fake SMTP Server online. The concept is similar to using SQLite as an in-memory database. Your tests will start your fake server, you send the email to this server, and then use your fake server to verify the email was sent as expected before stopping it. The next example is from Phil Haack and the implementation he used for his SubText open source project. The code can be downloaded from http://haacked.com/archive/2006/05/30/ATestingMailServerForUnitTestingEmailFunctionality.aspx.

The concept is simple. Imagine you have the following test:

[Test]
public void CanSendEmail()
{
   var notification = new Notification {Text = "Test"};
   EmailService service = new EmailService("localhost", 25);
   bool result = service.SendNotification(notification);
   Assert.IsTrue(result);
}

At the moment this will fail because localhost doesn't have an SMTP Server setup. To solve this, use your Setup method to start your TestFake server. You need to ensure that the two are communicating on the same port number:

[SetUp]
public void Setup()
{
   receivingServer = new TestSmtpServer();
   receivingServer.Start("127.0.0.1", 25);
}

After you are done, stop the server in your Teardown method:

[TearDown]
public void Teardown()
{
   receivingServer.Stop();
}

To verify your email was sent, ask your fake server for its inbox count. If it is 1, then the email sent was expected:

Assert.AreEqual(1, receivingServer.Inbox.Count);

You now have your EmailService object fully tested at both levels.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.235.176