How would this be useful

I'm still in the process of learning the how, when and wheres of Rhino Mocks. I just finished watching this tutorial: http://dimecasts.net/Content/WatchEpisode/12, I even typed it out using 3.5+ AAA syntax from Record/Playback but my question is how is this useful what can you do w/ this. I'm fundamentally missing something.

public class EmailerService
{
    public bool SendEmail(string email, string message)
    {
        return false;
    }
}

public class Emailer
{
    private IEmailerService _emailerService;
    public Emailer(IEmailerService emailerService)
    {
        this._emailerService = emailerService;
    }

    public void SendBatchEmails()
    {
        var emails = new Dictionary<string, string>
                        {
                            {"[email protected]", "Hello1"},
                            {"[email protected]", "Hello2"},
                            {"[email protected]", "Hello3"},
                            {"[email protected]", "Hello4"}
                        };
        foreach(KeyValuePair<string, string> email in emails)
        {
            if(!_emailerService.SendEmail(email.Key, email.Value))
            {
                throw new Exception(" You've Err'd");
            }
        }
    }
}

My Test are as follows:

        [TestMethod]
    public void EmailerServiceTest()
    {
        //Arrange
        var emailerServie = MockRepository.GenerateMock<IEmailerService>();
        emailerServie.Expect(x => x.SendEmail("", "")).IgnoreArguments().Return(true).Repeat.Any();

        //Act
        var emailer = new Emailer(emailerServie);
        emailer.SendBatchEmails();
    }


    [TestMethod]
    public void EmailerServiceTestException()
    {
        //Arrange
        var emailerServie = MockRepository.GenerateMock<IEmailerService>();
        emailerServie.Expect(x => x.SendEmail("", "")).IgnoreArguments().Throw(new Exception("You've Err'd"));

        //Act
        var emailer = new Emailer(emailerServie);
        emailer.SendBatchEmails();
    }

If you know when and where it will fail whats the point of writing a test where you already know the answer? Thanks

Upvotes: 2

Views: 111

Answers (2)

Gene C
Gene C

Reputation: 2030

Your tests so far look like you are on the right path. If your tests seem obvious, that is a good thing. They are there to ensure expected behavior. If months from now you have forgotten about Emailer but you change EmailerService to throw an exception on a failure, instead of return false, your tests will remind you that Emailer is expecting different behavior and needs to be updated.

When writing unit tests, I always do two things before any implementation: 1) writing a clear test function name, and divide the method into the three components Arrange, Act, Assert. This helps me to keep my expectations of the test clear, and to ensure that I don't forget anything.

It appears as if you have forgotten to include the Assert portion of the test:

[TestMethod]
public void Emailer_IsCalled_SendEmailIsCalled()
{
    //Arrange
    var emailerService = MockRepository.GenerateMock<IEmailerService>();
    emailerServie.Expect(x => x.SendEmail("", "")).IgnoreArguments().Return(true).Repeat.Any();

    //Act
    var emailer = new Emailer(emailerService);
    emailer.SendBatchEmails();

    //Assert
    emailer.VerifyAllExpectations();
}

In the second test, it seems that you want to test that if SendEmail fails an exception is thrown. In this case, emailerService is better suited as a Stub:

[TestMethod, ExpectedException(typeof(Exception))]
public void Emailer_SendEmailReturnsFalse_ThrowException()
{
    //Arrange
    var emailerService = MockRepository.GenerateStub<IEmailerService>();
    emailerServie.Stub(x => x.SendEmail("", "")).IgnoreArguments().Return(false);

    //Act
    var emailer = new Emailer(emailerService);
    emailer.SendBatchEmails();

    //Assert
    //Expect Exception
    /* Even when I don't have and assert call here, I usually leave a note*/
}

Upvotes: 2

Gishu
Gishu

Reputation: 136613

Something's wrong.

I think you want to test

  • when emailer.SendBatchEmails is called.. it delegates to emailerService.SendEmail.
  • when emailer.SendBatchEmails is called and emailerService returns a failure (by returning false), then an exception should be thrown.

In the first test, you should verify that emailerService.SendEmail was in fact called (missing) For the second, the mock should be setup to return false. The test method should be setup to expect an exception with the specific error message.

Upvotes: 3

Related Questions