Home Contact

Igor Milovanović

.NET, cats and more...

News

Article Categories

Archives

Post Categories

Image Galleries

Blogs I read

Communities

Links

Syndication:

Using Mock Objects in Unit Tests

Only two weeks until TechEd Europe 2004. I am really looking forward to it. Almost one week of hard work, visiting technical sessions, learning new technologies and making new and interessting contacts. The conference takes place in Amsterdam, which is well known as a dull and no-fun-at-all-whatsoever-city, so that I won't have any problems concentrating on my work. (Just for the case my employer is reading my blog... ) 

As I am leaving for a week I will need somebody to take care of my "bad cats". They are actually quite intelligent beasts, but they still haven't learned how to open a can of cat food by themselves. The trouble with cat sitters however is that you can't really trust them. You don't know if they really do the work as they promise and sometimes I would like to test them first before deciding to trust them. I don't want to use my cats as test objects however. They can be annoying from time to time but basically I still like them...

So let's take a look at this scenario written in CSharp:

A cat is described with an interface ICat which defines some basic cat behaviour:

///


/// The interface describes basic cat behavior.
///

interface ICat
{
    string Name
    {
        get; set;
    }

    void Eat ();
    void Sleep ();
    void Meow ();
}
  

The only thing a cat sitter should do is to feed the cats:

///


/// a cat sitter
///

class CatSitter
{
    ArrayList _cats = new ArrayList ();

    public void TakeCareOf(ICat cat)
    {
        _cats.Add (cat);
    }

    public virtual void DoWork ()
    {
        foreach (ICat cat in _cats)
        {
            FeedCat (cat);
        }
    }

    private void FeedCat (ICat cat)
    {
        cat.Eat ();
    }
}

And let's assume that some cat sitters are to lazy to do their work:

///


/// lazy cat sitter
///

class LazyCatSitter : CatSitter
{
    public override void DoWork()
    {
            // do nothing
    }
}

Like I said before I don't want to use my cats for a test. This can happen in real world scenarios when you only want to test interaction between objects before there is any implementation of the interface. I am going to use dynamically created implementation object from the interface  (a mock object) to test my cat sitters, with the help of NMock  library.

Let's test the lazy cat sitter first:

[Test]
public void LazyCatSitterTest ()
{
    LazyCatSitter lazyCatSitter = new LazyCatSitter();
    
    DynamicMock funnyBunny = new DynamicMock (typeof (ICat)); // creating a dynamic instance
    DynamicMock baerchen = new DynamicMock (typeof (ICat)); // for a interface

    lazyCatSitter.TakeCareOf ((ICat) funnyBunny.MockInstance);
    lazyCatSitter.TakeCareOf ((ICat) baerchen.MockInstance);

    funnyBunny.Expect ("Eat", null); // we expect that the eat method 
    baerchen.Expect ("Eat", null); // has been called

    lazyCatSitter.DoWork ();

    funnyBunny.Verify (); // verify that the eat method
    baerchen.Verify (); // has been called
}

This code throws the "NMock.VerifyException - Eat () never called". The cats didn't get anything to eat! Good thing that I tested this guy first  ;-)

The mock objects are a usefull tool for testing object interaction, especially than when you are developing "test first" or when it is too difficult/complicated to reproduce the whole environment for a class in a test case.

Just for the sake of consistency, here is the test of the girl I am hiring for cat sitting: Now I am sure that the cats will be well fed.

[Test]
public
void CatSitterTest ()
{
     
    DynamicMock funnyBunny = new DynamicMock (typeof (ICat));
    DynamicMock baerchen = new DynamicMock (typeof (ICat));

    CatSitter myCatSitter = new CatSitter ();
    myCatSitter.TakeCareOf ((ICat) funnyBunny.MockInstance);
    myCatSitter.TakeCareOf ( (ICat) baerchen.MockInstance);

    funnyBunny.Expect ("Eat", null);
    baerchen.Expect ("Eat", null);

    myCatSitter.DoWork ();

    funnyBunny.Verify ();
    baerchen.Verify ();
}


 

[1] Extreme Programming Rules - Test First
[2] NMock
[3] Mock Objects

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Thursday, September 23, 2004 11:35 AM

Feedback

No comments posted yet.


Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: