- Move as much common setup logic to a base class as possible.
- Use your class name as the context
- methods are rules beginning with "should"
- create a new subclass of the base context every time you have a new scenario
public class BaseAddVacationContext
{
protected AddVacationRequest submission;
protected IEmailSender _sender;
protected IUserInformation _information;
protected ICrudRepo<LeaveRequest> _leaverepo;
protected LeaveRequest request;
[SetUp]
public virtual void SetUp()
{
_sender = MockRepository.GenerateMock<IEmailSender>();
_information = MockRepository.GenerateMock<IUserInformation>();
_leaverepo= MockRepository.GenerateMock<ICrudRepo<LeaveRequest>>();
submission = new AddVacationRequest(_sender, _information, _emprepo);
request = new LeaveRequest() { UserName = "james" };
}
}
[TestFixture]
public class SpecAddVacationRequestWhenHappyPathOccurs : BaseAddVacationContext
{
[SetUp]
public override void SetUp()
{
base.SetUp();
_information.Stub(x => x.GetManagersEmailAddresses("james")).Return(new[]{"jacob@jonbank.com", "johnny@jonbank.com"});
_information.Stub(x => x.GetUserEmail("james")).Return("james@jonbank.com");
submission.Execute(request);
}
[Test]
public void should_email_all_managers()
{
_sender.AssertWasCalled(x => x.Send(Arg <Message>.Matches(y => y.To == "jacob@jonbank.com")));
_sender.AssertWasCalled(x=>x.Send(Arg <Message>.Matches(y=>y.To =="johnny@jonbank.com")));
}
[Test]
public void should_send_email_to_user()
{
_sender.AssertWasCalled(x => x.Send(Arg <Message>.Matches(y => y.To == "james@jonbank.com")));
}
[Test]
public void should_store_leave_request_in_database()
{
_emprepo.AssertWasCalled(x=>x.Create(Arg <LeaveRequest>.Matches (u=>u == request)));
}
}
So here we have:
- A setup that you need to override and call to setup context specific behavior
- small small tests and asserts.
- limited setup on mocks, you can use handrolled mocks or the real classes if you prefer (which I do often).
- Use AssertWasCalled instead of .Expect() on my mocks
No comments:
Post a Comment