Reputation: 978
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
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
Reputation: 136613
Something's wrong.
I think you want to test
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