.NET and me Coding dreams since 1998!

17Feb/071

James Carr » Blog Archive » TDD Anti-Patterns

Link to James Carr » Blog Archive » TDD Anti-Patterns


James Car gathered an excellent collection of TDD anti patterns which is HAVE TO for every TDD oriented developer


Bookmark it at once! :)


Filed under: Uncategorized 1 Comment
11Feb/070

Web Service Software Factory (WSSF)

Versioning Web Services


Don Smith, PM of Web Service Software Factory P&P team has an interesting conceptual post about one of the coolest improvement done for December release: message versions.


I believe this could help in understanding the new versioning related receipt in WSSF


Link to Don Smith blog post: Emerging Guidance


Web Service Software Factory–December 2006 (ASP.NET and WCF services in C#)


Useful new articles


Add to that examinations of excellent February MSDN Magazine Service Station article of Aaron Skonnard and reference implementation which combines WSSF and WCSF and I believe the whole WSSF magic would start to be sweet as apple pie :)


Aaron latest Service Factory article about the December release


Reference Implementation built with WC-SF and WS-SF


 


Filed under: Uncategorized No Comments
5Feb/077

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 code by 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 in RateCardPresenter.cs there's next constructor:

public RateCardPresenter(IRateCardView view, IRateCardDataSource dataSource)
{
      _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 mock type interface implementation which would be something like:

internal class 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 frameworks

That problem  is been solved by couple of dynamic mocking frameworks such as: NMockEasyMock.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.

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]

public void InitTest()

{

      _mockery = new MockRepository();

      _dataSource = _mockery.DynamicMock<IRateCardDataSource>();

}

(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 using that 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 world is 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. I just 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

// 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);

 

            // 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 the ratecard 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 report 1")

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 using multiply 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 of the expectations fulfilling is been examined and the success/fail result is been propagated 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(_dataSource.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 of rhino 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

 

 


Share this post :

Filed under: Uncategorized 7 Comments
3Feb/071

TDD is cool, but..

Recently I gave a presentation to my company HQ in Maynard, Massachusetts, USA where I tried to present the importance and benefits of Test Driven Development.

The purpose of presentation was to present MVP design pattern as a way that we can decouple our presentation logic from the UI elements. Doing this would enable unit testing of the UI business logic located in the presenter. I had a rough time because the whole presentation was only an hour and a half. I spent a lot of time explaining our current business problems that MVP and test driven development can solve. Anyhow, after half an hour of talking really fast I somehow gave a general overview of MVP and, judging by the people’s faces, I think I sold them on the usefulness of MVP in WebUI.

But some problems emerged in second part of the session, when I had only 20 minutes to present the concept of dynamic mocking as a way of writing tests for the presenter before implementing the presenter. Explaining what is mocking and how it works, the benefits of dynamic mocking, and some general overview of what Rhino mocks are took 20 minutes, so when I started to write first test tp describe presenter initialization behavior, time ran out.

In the last five minutes of wrapping up I heard a couple of typical questions which I hear all the time when I'm trying to present the usefulness of TDD to someone.

Some of the questions are:

  1. It is cool, but we would spent a lot of time writing test scripts.
  2. It is cool, but we are not using real objects for testing, so test results with real objects might be different.
  3. It is cool, but it requires that developer has intimate knowledge about the tested code at the moment when the tests are been written.
  4. It is cool, but we have already a functional requirement document (FRD) which describes the same things, so writing test would only double our efforts.

My short replies:

1. True, but only if you are not unit testing your code at all. If you are writing unit tests after the code is written, I believe there is an obvious additional benefit of using the tests (during development) as a guideline. Another advantage is that these behavioral tests may be the best type of functional documentation. They quickly and precisely give other developers an overview of the purpose and usage of the component.

2. False. When you are testing the presenter, you are writing tests for the presenter class itself, not the presenter mock, so nothing would change "after". You are mocking view and data source only, and they are not the test subjects.

3. False. Default recording mode of the rhino mocks is Unordered, which means: "I expect that public presenter method call would make something happen inside presenter which would produce some effect on the view interface but I don't know what would happen, when it would happen, and in which order." That sounds pretty "black boxed" to me.

4. True. At least, if you don't care about the time and money spent on the incorrect code implementation cause by misinterpreting the FRD. By relying on word documents, there's no way to guarantee that requirements are fulfilled. The only way to verify that the requirements are satisfied is testing during QA phase when all the code is been already done. By this point, any misunderstood FRD requirement will cause (sometimes significant) code changes, which lead to another QA phase, etc. In my opinion, an FRD word document is not a technical document.  It is a business document which belong in to the Land Of Suits. The Technical FRD is the set of behavioral unit tests translated from Word FRD document. Developers shouldn't care about word documents. These functional tests also allow for transparent progress tracking. If 10 of the 30 tests pass, that means the task is 33% complete.

My next blog will be about the second part of my presentation: Rhino mocks- usage, benefits, and TDD.

Until then you can take a peek at the code sample I used in my presentation:

MVP & TDD Example source code

(You'll need VS2005, NUnit and Rhino Mock installed on your computer to run the example.)

 

Filed under: Uncategorized 1 Comment