Paulo Morgado

.NET Development & Architecture

This Blog

Syndication

Search

Sponsored By

Tags

News

Unit Test Today! Get Typemock Isolator!

Books

 

Visitors

Visitor Locations

Community

Email Notifications

Archives

Profile

Disclaimer

The opinions and viewpoints expressed in this site are mine and do not necessarily reflect those of Microsoft, my employer or any community that I belong to. Any code or opinions are offered as is. Products or services mentioned are purchased by me, made available to me by my employer or the manufacturer/vendor which doesn't influence my opinion in any way.

Unit Testing and Mock Frameworks

I'm not a big fan of Test Driven Development (TDD), but I love Unit Testing.

But to be productive on unit testing I need a good framework for Mock Objects. I can't expect to be productive and have to build a lot of mock classes to test other classes. And, who tests the mock classes?

Mock objects simulate the behavior of real objects when they are difficult or impossible to obtain.

I've been testing a few mock frameworks and this is my opinion (*) on the ones I've tested.

NMock

I've been introduced to NMock by Jean-Paul Boodhoo and his series of articles (MSDN) and shows (dnrTV).

NMock is an open source project that you can use, providing you abide to their conditions.

NMock is expectation based and has one really neat feature that I like: the ability to scope the mocks. I can write a test like this:

using (Mockery mockery = new Mockery())

{

    ISomeInterface instance = mockery.NewMock<ISomeInterfac>();

    Expect.Once.On(instance).Method("SomeMethod").With(Is.EqualTo(SomeValue)).Will(Return.Value(true));

    Assert.IsTrue(instance.SomeMethod(SomeValue));

}

As you can see, you just define a mock scope by instantiating a Mockery object and disposing of it in the end. In between, you just declare what you expect to happen.

What I don't like is the fact that I don't have compile time checking on the mocked members. If I need to do some refactoring on ISomeInterface I will have to go all over my tests and change the strings defining ISomeInterface's members.

At this time NMock doesn't handle mocking Generics, which makes it useless to me.

Support is mainly provided through a community group.

NMock also seems to be a dead project at this time.

Rhino.Mock

Through MockObjects.com I came to Rihno.Mocks. Rihno.Mocks is the result of Ayende's open source project and free to use, providing you abide to his conditions.

As I understand it, Rhino.Mocks has dropped the scope feature present in NMock but, besides the expectation mechanism, it has a recording mechanism. It's as easy as follows:

MockRepository mocks = new MockRepository();

 

IDemo demo = mocks.CreateMock<IDemo>();

// Setting up an expectation for a call to IDemo.VoidNoArg   

demo.VoidNoArg();   

mocks.ReplayAll();   

// Fullifying the expectation for call to IDemo.VoidNoArg   

demo.VoidNoArg();

 

mocks.VerifyAll();

However, the last version of Rhino.Mocks I tested didn't support mocking Generics, which (as I said before) makes it useless to me. But there's hope, a new version is on the way.

Support is mainly provided through a community group.

TypeMock.NET

This is my favorite. Have you ever thought you could do this?

string username = "test";

 

using (RecordExpectations recorder = RecorderManager.StartRecording())

{

    recorder.ExpectAndReturn(HttpContext.Current.ApplicationInstance.User.Identity.Name, username);

}

 

string expected = username;

 

Assert.AreEqual(expected, HttpContext.Current.ApplicationInstance.User.Identity.Name);

 

TypeMock.MockManager.Verify();

Well, you will on the next release.

And you can mock classes with generic methods:

public class Test { public T DoIt<T>(T t) { return t; } }

 

[TestMethod()]

public void NaturalMockTest()

{

    MockManager.Init();

    Mock testMock = MockManager.Mock(typeof(Test));

 

    Test t = new Test();

 

    Assert.AreEqual(3, t.DoIt(3));

    Assert.AreEqual("something", t.DoIt("something"));

}

TypeMock has 3 versions: Community, Professional and Enterprise. The Community version is free but you will have to pay for the other two.

TypeMock supports two types of mocks: Reflective Mocks and Natural Mocks™.

TypeMock's Reflective Mocks by declaring the behavior of classes using its members' names:

public bool IsAuthenticated(string name, string password)

 

{

    Logger.Log(Logger.NORMAL, "Entering Authentication");

    try

    {

        // do something

        int Results = DoSelect(statement);

        bool isOk = Results == 1;

        if (isOk)

        {

            Logger.Log(Logger.NORMAL, "User Authenticated " + name);

        }

        else

        {

            Logger.Log(Logger.SECURITY, "User login failed " + name);

        }

        return isOk;

    }

    catch (Exception ex)

    {

        Logger.Log(Logger.FAILED, "Login system failure", ex);

        // handle exception

    }

}

 

[TestMethod]

public void Authenticated()

{

    Authentication authenticator = new Authentication();

    // Initialize Type Mocks (This can be done in the [Setup])

    MockManager.Init();

    // the Logger class is now being mocked

    Mock logMock = MockManager.Mock(typeof(Logger));

    // set up our expectations for 2 Log calls in IsAuthenticated

    // 1) "Entering Authentication" Log at first line

    // 2) "User login failed user" Log

    logMock.ExpectCall("Log");

    logMock.ExpectCall("Log");

 

    // authentication should fail

    Assert.IsFalse(authenticator.IsAuthenticated("user", "password"));

    // Verify that all calls were made (This can be done in the [Teardown])

    MockManager.Verify();

}

Natural Mocks™ on the other hand, support recording of expectations:

[TestMethod]

public void Authenticated()

{

    Authentication authenticator = new Authentication();

    // set up our expectations for 2 Log calls in IsAuthenticated

    // 1) "Entering Authentication" Log at first line

    // 2) "User login failed user" Log

    using (RecordExpectations recorder = RecorderManager.StartRecording())

    {

        // CAUTION: ALL calls here are mocked!!!

        Logger.Log(Logger.NORMAL, null); // 1

        Logger.Log(Logger.NORMAL, null); // 2

    }

    // Thats it folks

 

    // authentication should fail

    Assert.IsFalse(authenticator.IsAuthenticated("user", "password"));

    // Verify that all calls were made (This can be done in the [Teardown])

    MockManager.Verify();

}

Too bad you can only have this on the Professional and Enterprise versions, but you'll get other stuff like code coverage and NAnt and MSBuild support.

 

TypeMock doesn't support mock scopes. Also makes no use of Generics forcing us to a constant use of casts.

TypeMock has support forums in its site and a great e-mail support. And they listen to suggestions (at least to, mine).


This is just my opinion on these mock frameworks and not an extensive analysis of mock frameworks or even the ones mentioned.

Published Sat, Feb 17 2007 23:51 by Paulo Morgado

Comments

# re: Unit Testing and Mock Frameworks@ Saturday, March 17, 2007 9:35 AM

POCMock is a good tool too!

You can mock anything, events, fields! ...

You can have whatever constraint you want on parameters, supports ref and out parameters mocking...

Ludovic Dubois

# re: Unit Testing and Mock Frameworks@ Saturday, March 17, 2007 4:36 PM

Thanks Ludovic. I didn't know that one.

Do you know if it mocks classes in mscorlib?

Paulo Morgado

# TypeMock.NET 4.0.0 is now available@ Sunday, May 20, 2007 2:34 PM

TypeMock.NET 4.0.0 is now available . In my previous analysis mentioned two drwanbacks of this mocking

Paulo Morgado

# re: Unit Testing and Mock Frameworks@ Monday, May 28, 2007 8:21 AM

NMock do support generics, and has been for over a year: http://sourceforge.net/project/shownotes.php?release_id=414351&group_id=66591

redsolo

# re: Unit Testing and Mock Frameworks@ Monday, May 28, 2007 11:00 AM

Maybe I missed something, but, when I used it, NMock2 had Generics in its API but did not support mocking types with Generics.

Paulo Morgado

# re: Unit Testing and Mock Frameworks@ Monday, August 25, 2008 7:38 AM

Mockito should also be noted.

You don't have to determine expectations and you can directly start to testing. I like it.

code.google.com/.../mockito

Emre

# re: Unit Testing and Mock Frameworks@ Monday, August 25, 2008 11:47 AM

Hi Emre,

This Mockito is a Java only mocking framework, right?

Paulo Morgado

# re: Unit Testing and Mock Frameworks@ Tuesday, September 16, 2008 11:50 PM

Suppose my ABC mrthod return 2 out paramters and i want to catch it into my calling method. like mockObj.ExpectAndReturn("methodname",,,)

Please help me in this regard

Prafful

# re: Unit Testing and Mock Frameworks@ Thursday, September 18, 2008 5:51 PM

Hi Prafful,

Check this out.

Paulo Morgado

# Faking Output Parameters With Typemock Isolator - Paulo Morgado@ Monday, October 06, 2008 3:51 PM

Pingback from  Faking Output Parameters With Typemock Isolator - Paulo Morgado

Faking Output Parameters With Typemock Isolator - Paulo Morgado

# Faking Output Parameters With Typemock Isolator - Paulo Morgado@ Monday, October 06, 2008 3:51 PM

Pingback from  Faking Output Parameters With Typemock Isolator - Paulo Morgado

Faking Output Parameters With Typemock Isolator - Paulo Morgado

# Paulo Morgado : Forjando Par&#226;metros De Sa&#237;da Com Typemock Isolator@ Monday, October 06, 2008 4:06 PM

Pingback from  Paulo Morgado : Forjando Parâmetros De Saída Com Typemock Isolator

Paulo Morgado : Forjando Parâmetros De Saída Com Typemock Isolator

Leave a Comment

(required) 
(required) 
(optional)
(required)