rhino mocks tutorial part 1

Upload: dawah786

Post on 10-Apr-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/8/2019 Rhino Mocks Tutorial Part 1

    1/5

    VusCode - Coding dreams since 1998!

    .NET exploration, articles, cool links, surf logs, book reviews, .net, c#, smart clients,

    software factories, patterns & practices, web casts and much more

    TDD - Rhino Mocks - Part 1 - Introduction

    Mocking is term which describes programing technique mostly used in Test Driven

    Development for writing tests of some entity with abstraction of its dependencies.

    The best example is MVP design pattern where we are implementing presenter codeby using Dependency Injection pattern to inject in presenter view implementation and

    maybe data source implementation during the run time.

    In my last post I provide MVP & TDD Example source code where inRateCardPresenter.cs there's next constructor:

    public RateCardPresenter(IRateCardView view, IRateCardDataSourcedataSource){

    _view = view; _dataSource = dataSource; Initialize();

    }

    In old days if I would like to mock data source in case when there's no *real* object, I

    would have to create static mocktype interface implementation which would be

    something like:

    internalclass RateCardDummyDataSource : IRateCardDataSource

    {

    #region IRateCardDataSource Members implementation #endregion

    }

    Problem with that implementation is that in real world scenarios results with swarms

    of dummy mock object which are useless once after the real implementation is been

    done and causes very big maintenance problems. Static mocks are maybe main reason

    why TDD didn't take the place which deserves in development methodology

    Mocking frameworksThat problem is been solved by couple of dynamic mocking frameworks such as:

    NMock, EasyMock.Net and my personal champion: Rhino mocks. They all use Proxy

    design pattern to create on the fly mock object which is implementing given interface.

    Advantage of RhinoMock is that has a lot of features: different mocking creation

    methods, enables usage of intellisense on mocked objects, explicit recording mode

    etc.

  • 8/8/2019 Rhino Mocks Tutorial Part 1

    2/5

    Rhino mocks explained in one sentence could (maybe) be: first we enlist ("record")everything we expect it would happened and then, after recording, we just check if

    our expectations were met.

    Dynamic mocking

    So in our case, mock creation of IRateCardDataSource with Rhino mocks would be

    simple:

    private MockRepository _mockery; private IRateCardDataSource _dataSource;

    ...

    [SetUp]publicvoid InitTest(){

    _mockery = new MockRepository(); _dataSource = _mockery.DynamicMock();

    }

    (For now, you can think about MockRepository as a kind of helper class which

    exposes Rhino mocks methods)

    By implementing that single line we have now _dataSource object which implements

    IRateCardDataSource and which we can use in our unit tests.

    But, this object is just a shell of the real object a kind of spy which imitates real object

    and tell us: "Hey, someone set on me property X and then call method Y". There's no

    data inside at all. I believe you would be asking by now what is the benefit of usingthat kind of mock ("Data source without the data is useless").

    TDD behavioral tests

    In TDD, one of the main principles is writing the tests for certain part of the code,

    before the code is been implemented. That it is been done because test in TDD worldis a kind of contract on desired behavior of the code tested. So, when I'm writing

    tests for my presenter methods before they exist I care to define presenter behavior

    and not data source behavior. I could say that I expect that inside of the presenter

    certain method would call datasource object and get some results. I don't care how

    datasource would get that data and (for now) what kind of data it would be returned. Ijust care about contracting presenter behavior. Something like:

    ...

    // expect first call to data service which would// return some rate card items Expect.Call(_dataSource.GetRateCardData(rateCardTypeID))

    .Return(rateCardItems );// expect that the view ratecarditem collection

  • 8/8/2019 Rhino Mocks Tutorial Part 1

    3/5

    // would be set to the result of data service _view.RateCardItems = rateCardItems;

    ...

    As you can see, I used mocked data source object to put expectation that somewhere

    inside of presenter presenter would call datasource method and expectation that those

    results would be set then on view dynamic mock object property.

    How this works: _dataSource and _view are "spays" which would tell to rhino mocks

    framework if the expected action on their method happened or not. If not Rhino mock

    would throw an exception which would be cached by NUnit and the test would fail.

    Recording modes

    In our previous example, if we would implement the presenter code on the way that

    _view would be set before the datasource would be called, both test would pass

    because both of the spays would report that their expectations were fulfilled.

    That's why in RhinoMocks we can set Mockery to direct mocking spays to check if

    the expectations happened in order given while we record our expectations.

    Something like:

    using (_mockery.Ordered()) {

    // expect first call to data service which would// return some rate card items Expect.Call(_dataSource.GetRateCardData(rateCardTypeID))

    .Return(rateCardItems); // expect that the view ratecarditem collection

    // would be set to the result of data service _view.RateCardItems = rateCardItems; }

    Which would cause our test failing if the expectations were not met in order they were

    recorded.

    The default behavior of the recording mode is Unordered, but you can combine

    "group" the expectations whatever you prefer. Something like:

    // default recording mode. Using block can be omitted using (_mockery.Unordered()){

    //expect that header message would be set to// header message of contract rate card _view.HeaderMessage = Constants.HEADER_MESSAGE_CONTRACT_CART;

    using (_mockery.Ordered()) {

    // expect first call to data service which would// return some rate card items Expect.Call(_dataSource.GetRateCardData

    (rateCardTypeID)).Return(rateCardItems);

  • 8/8/2019 Rhino Mocks Tutorial Part 1

    4/5

    // expect that the view ratecarditem collection// would be set to the result of data service _view.RateCardItems = rateCardItems;

    }}

    Which would mean: I don't know if the header message would be set before theratecard data source group of expectation or after, but I do expect that whenever

    datasource group expectations would start, they would execute in expected order.

    Setting up mock values

    Well, for certain presenter action could depend on certain mock object values, so for

    some test we would have to set the view to desired state ("set up the stage for

    recording")

    We can do that by setting expectations like:

    Expect.Call(_view.RateCardProductType).Return(1);

    Which means: When presenter would check the view RateCardProductType property

    of the mock he should get the value of 1 from the mocked object ("spy would report1")

    By default all of the expectations are single expectations, so if presenter would try to

    get that value for the second time somewhere in the code he would get null value.

    But that breaks the concept of the black box presenter implementation in the moment

    of writing tests, so in case when I don't expect exactly one call, I'm usually usingmultiply value setting retrieval expectations. Something like:

    Expect.Call(_view.RateCardProductType).Return(1).Repeat.AtLeastOnce();

    which offers much more customization over the preoperative expectations

    or simple

    SetupResult.For(_view.RateCardProductType).Return(1);

    Both of them are the same: Whenever someone asks for RateCardProductType returns

    him 1.

    Play!

    End of the recording mode is been signalized to MockeryType by simple call of

    ReplyAll() method. Results of every line after that are been compared with the spy

    expectations until the MockeryType.VerifyAll() method call when the successfulness

  • 8/8/2019 Rhino Mocks Tutorial Part 1

    5/5

    of the expectations fulfilling is been examined and the success/fail result is beenpropagated to NUnit framework as a passed/failing test. Something like this

    // default recording mode. Can be omitted using (_mockery.Unordered()){

    //expect that header message would be set to

    // header message of contract rate card _view.HeaderMessage =

    Constants.HEADER_MESSAGE_CONTRACT_CART;

    using (_mockery.Ordered()) {

    // expect first call to data service which would// return some rate card items Expect.Call(_dataS ource.GetRateCardData

    (rateCardTypeID)).Return(rateCardItems); // expect that the view ratecarditem collection// would be set to the result of data service _view.RateCardItems = rateCardItems;

    }

    }

    // stop recording actions and start verify mode _mockery.ReplayAll();

    // init presenter class RateCardPresenter presenter =

    new RateCardPresenter(_view, _dataSource);

    // propagate to Nunit status of behavioral expectations _mockery.VerifyAll();

    Conclusion

    That would be all for now - I hope you've got the big picture which was the point of

    this intro article :)

    Next parts of Rhino mock article series would cover in more details every aspect ofrhino mocks framework + some of my real world "gotcha type" experiences in using

    it

    Update: Part 2 of the rhino mock can be found here Rhino Mock Part 2 -Common scenarios