Rhino Mocks


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Rhino Mocks

  1. 1. Rhino Mock Implemetation ProcessFor Implementing the Mocking, I used Rhino.Mocks Namespace of version No during unit testingin my project.Before starting we just need to know basic knowledge about Rhino Mocks,i.ewhat is Rhino Mockswhat is a AAA..what is difference b/w Mock and Stub.Rhino MocksA dynamic mock object framework for the .Net platform. Its purpose is to ease testing byallowing the developer to create mock implementations of custom objects and verify theinteractions using unit testing.Rhino Mocks allows you to easily create mock objects and setup a wide range of expectations onthem using strongly typed notation instead of compiler-opaque strings.AAA Syntax - Arrange, Act, AssertThis is where Rhino Mocks 3.5 is really interesting - for me at least. We can now express ourmock object is a much cleaner fashion, taking advantage of .Net 3.5 extension methods andlambda questions. Below, is the example of using the Mock object.[Test]public void GenerateMock_TakePaymentViaPaymentProcessorUsingMockService(){ IPaymentProcessing mockProxy = MockRepository.GenerateMock<IPaymentProcessing>(); #1 mockProxy.Expect(x => x.TakePayment(1, 1, 10.0)) #2 .Constraints(Is.Equal(1), Is.Equal(1), Is.Equal(10.0)) .Return(true); PaymentProcessor pp = new PaymentProcessor(mockProxy); bool result = pp.TakePayment(1, 1, 10.0); Assert.IsTrue(result);
  2. 2. mockProxy.VerifyAllExpectations (); #3}#1 Here we tell Rhino Mocks to create us a mock object of type IPaymentProcessing.#2 Next we define our mock. Here, we are saying we expect TakePayment to be called, we thenadd some constraints about what the parameters passed in much be, finally defining that truebe returned when this is called.#3 Finally, we verify the exceptions we set in #2 where correct.I find this new approach to be much easier to read, explain and write. The first time I tried this, Iactually mistaken Constraints for Return and as such the following exception was thrown.mockProxy.Expect(x => x.TakePayment(1, 1, 10.0)).Constraints(Is.Equal(true)); = failed:System.InvalidOperationException : The number of constraints is not the same as the number ofthe methods parameters!Just be aware of these new constraints on the parameters.But, not only can we use this for creating mocks, but we can also create Stubs.[Test]public void GenerateStub_TakePaymentViaPaymentProcessorUsingMockService(){ IPaymentProcessing stubProxy = MockRepository.GenerateStub<IPaymentProcessing>(); #1 stubProxy.Stub(action => action.TakePayment(1, 1, 10.0)).Return(true); #2 PaymentProcessor pp = new PaymentProcessor(stubProxy); bool result = pp.TakePayment(1, 1, 10.0); Assert.IsTrue(result);}#1 Generate the stub#2 Define the stubHow cool is that!! Two lines of code to create our stub![Test]public voidGenerateStub_AssertWasCalled_TakePaymentViaPaymentProcessorUsingMockService(){ IPaymentProcessing stubProxy = MockRepository.GenerateStub<IPaymentProcessing>(); stubProxy.Stub(action => action.TakePayment(1, 1, 10.0)).Return(true);
  3. 3. PaymentProcessor pp = new PaymentProcessor(stubProxy); bool result = pp.TakePayment(1, 1, 10.0); Assert.IsTrue(result); stubProxy.AssertWasCalled(x => x.TakePayment(1, 1, 10.00)); #1}#1 With stubs, we can also verify that the method was called. Notice this AssertWasCalled is anextension method Rhino Mocks has added to the interface. gain, this is helping with thereadability and demonstrates an excellent use of Extension Methods.If AssertWasCalled failed, then the following exception would be thrown and the test wouldfail.Expected that IPaymentProcessing.TakePayment(1, 1, 10); would be called, but it was not foundon the actual calls made on the mocked object.The difference between stubs and mocksI want to focus on the difference from the point of view of Rhino Mocks.A mock is an object that we can set expectations on, and which will verify that the expected actionshave indeed occurred. A stub is an object that you use in order to pass to the code under test. You cansetup expectations on it, so it would act in certain ways, but those expectations will never be verified. Astubs properties will automatically behave like normal properties, and you cant set expectations onthem.If you want to verify the behavior of the code under test, you will use a mock with the appropriateexpectation, and verify that. If you want just to pass a value that may need to act in a certain way, butisnt the focus of this test, you will use a stub.IMPORTANT: A stub will never cause a test to fail.No Expects then no need to call VerifyAllExpectations() .We also Crearte for GenerateMock in any abstract class ,for examplenamespace Corp.Database{ public abstract class DatabaseCommand : IDisposable { protected DatabaseCommand(string query); protected DatabaseCommand(string query, string[] parameterNames,params object[] parameters);}
  4. 4. }// In the Test cs containsnamespaceTests.CustomerCare.Infrastructure.Refund.RefundRequestRepositoryTests{ public partial class RefundRequestRepositoryTests {private DatabaseCommand CreateDeleteCommand(long ticketId) { DatabaseCommand command =MockRepository.GenerateMock<DatabaseCommand>("storedProcName"); _commandFactory.Expect(cf =>cf.CreateDeleteCommand(ticketId)).Return(command); return command; }}}Then after thatWe can take Tests.CustomerCare project . In that project take one classCallDetailsPresenterTests.csnamespace Tests.CustomerCare{ [TestFixture] public class CallDetailsPresenterTests { private CallDetailsPresenter _presenter; private ITicketRepository _ticketRepository; }[SetUp] public void Setup() { private CallDetailsPresenter _presenter; _ticketRepository = MockRepository.GenerateMock<ITicketRepository>();//Generate Mock and Generate Stub can only be created for interfaces. #1
  5. 5. _presenter = new CallDetailsPresenter(navigateCommandFactory,…); //Initilizing the class object ..}[TearDown] public void TearDown() { _ticketRepository.VerifyAllExpectations();#3//It verifies all exceptions}[Test] public void CanUpdateCall() { _ticketRepository.Expect(tr =>tr.Populate(_ticketId,_ticketHistoryRepository,_ticketAttachmentRepository,_ticketDiscRepository,_transactionRepository,_refundRequestRepository)).Return(_fakeTicket);// Expect method was placed inin any presnter .. #2Then after that call the particular presenter._presenter.Save(sendEmail);// after invoking the method in the presenter all the Expect methods areinvoked and verifications of this expections are done in teardown.}Implementation is developed in the TicketRepository class file,Method name ispublic ITicket Populate(long ticketId, ITicketHistoryRepositoryhistoryRepository, ITicketAttachmentRepository attachmentRepository,ITicketDiscRepository discRepository, ITransactionRepositorytransactionRepository, IRefundRequestRepository refundRequestRepository) {Return ticket;}But Method was called into CallDetailsPresenter
  6. 6. Create or initilizevalue.. private readonly ITicketRepository _ticketRepository;public CallDetailsPresenter(ICallDetailsView view, ICustomerCareUser user,ITicketRepository ticketRepository, ITicketViewBinder ticketViewBinder, ITicketHistoryRepository ticketHistoryRepository,ITicketAttachmentRepository ticketAttachmentRepository, ITicketDiscRepository ticketDiscRepository,ITransactionRepository transactionRepository, ITicketActionServiceticketActionService, IRefundRequestRepository refundRequestRepository,INavigatorCommandFactory navigatorCommandFactory){_ticketRepository = ticketRepository;// Create Object Initlization}Save(){update();}Update(){ITicket ticket = _ticketRepository.Populate(ticketId,_ticketHistoryRepository, _ticketAttachmentRepository, _ticketDiscRepository,_transactionRepository, _refundRequestRepository);//Expert is successfully saved.}