devxlogo

Isolating Dependencies in Tests Using Mocks and Stubs

Isolating Dependencies in Tests Using Mocks and Stubs

o test a class, a developer must make sure that the class’s dependencies won’t interfere with its unit tests. Enter mocks and stubs.

Unit tests check on the behavior of units. Think of a class as being a unit. Classes, more often than not, have external dependencies. Tests for such classes should not use their real dependencies because if the dependencies have defects, the tests fail, even though the code inside the class may be perfectly fine.

Suppose you aren’t feeling well and go to the doctor to find out what’s wrong. The doctor looks at you and quickly says, “You have a problem. How helpful would that be? Without knowing what kind of problem, it’s impossible for you to treat it, or to know whether it’s a serious problem, or whether it’s something that will go away in a day or two.

Instead, the doctor should ask you a couple of questions, analyze the symptoms, decide on a series of exams appropriate to your condition, isolate the variables to diagnose more accurately what’s wrong with you, and finally, prescribe the best treatment. After the treatment is complete, the doctor must conduct a few more tests to make sure everything’s all right.

Properly written unit tests isolate the system under test from its dependencies, facilitating the identification of defective areas of an application.

Can you draw the parallel with software development here? How many times have users come to you to say, “Your application doesn’t work“? That sentence alone doesn’t give you enough information to prescribe any cure for your software. You have to run the application through a series of exams so you can pinpoint where the problem is, apply a fix?and then run exams again to ensure you fixed the problem. The exams themselves must be isolated from one another (they mustn’t interfere with each other).

This article explores how to isolate a class being tested, also called system under test (SUT from here on), by using fake objects. You’ll see how to create static fake objects, as well as how to use dynamic fake objects created by an isolation framework (also called a mock framework).

The Scenario

This article uses a simple Windows Foundation Presentation (WPF) application as the basis for all samples. Figure 1 shows the main (and only) screen for this application.

?
Figure 1. Main Screen: Here’s the main screen of the WPF sample application used in this article.

The sample application keeps a list of videos. Each video has a title and a type (BluRay, DVD, or VHS). A user clicks the “Get Movies” button (see Figure 1) to retrieve the list, which can be filtered by video type. The user can then click any video in the list, causing the application to display the details for the movie at the bottom of the screen.

Granted, this is an overly simplistic application, but that’s good, because it lets you concentrate on what you are ultimately trying to learn here, which is mocks and stubs.

One particular aspect of this application is that it’s implemented based on the Model-View-PresentationModel (MVP) design pattern (or Model-View-ViewModel, which is pretty much the same thing).

This pattern promotes better separation of concerns, by keeping the part that the user sees (the “view”) as thin as possible; meaning that it should have as little code as possible. The main logic behind a view goes into a separate object: the “presentation model.” The presentation model object interacts with a “model” object, which provides the main data exposed by the view.

The follow is the code behind the main view for the application; the VideosListView class, which inherits from the Window class and implements IVideosListView:

public partial class VideosListView : Window, IVideosListView{   public IVideosListPresentationModel Model   {      get       {          return this.DataContext as IVideosListPresentationModel;       }      set { this.DataContext = value; }   }   private void listView_SelectionChanged(object sender,         SelectionChangedEventArgs e)   {      ShowVideoDetailsRequested(this,          new OpenVideoRequestedEventArgs(         listView.SelectedItem as Video));   }   private void getVideosButton_Click(object sender,       RoutedEventArgs e)   {      var selectedType = videoTypeComboBox.SelectedItem.ToString();      VideoListRequested(this,          new VideoListRequestedEventArgs(selectedType));   }   public event EventHandler         ShowVideoDetailsRequested = delegate { };   public event EventHandler         VideoListRequested = delegate { };}

You’ll notice there isn’t much to it. The class exposes a Model property of type IVideosListPresentationModel; as the name suggests, that’s the presentation model for this view (the view binds its UI controls to properties on this presentation model).

Other than that, the view simply raises a few events when important things happen, but doesn’t know or care what to do beyond raising the events (that’s not part of its responsibilities). The events it raises are ShowVideoDetailsRequested (whenever the user selects a video from the list), and VideoListRequested (whenever the user requests the list of videos by clicking on “Get Videos”). All those members are defined in the IVideosListView interface.

Make sure to download the sample code for the application. This article shows only those pieces of code relevant to the point being explained.

Your main task in this article is to write unit tests for the VideosListPresentationModel class, which is the SUT.

Editor’s Note: This article was first published in the May/June, 2009 issue of CoDe Magazine, and is reprinted here by permission.

Dealing with SUT Dependencies

The VideosListPresentationModel class has two dependencies: an object that implements IVideosListView, and an object that implements IVideosRepository. When writing tests for your SUT, you need to isolate those dependencies.

The first set of tests check to make sure the presentation model’s initial state has been properly set. There are three things to check for:

  • The object’s View property should have a reference to the view object passed to its constructor.
  • The Model property on the given view object should have a reference to the presentation model itself.
  • No filter should be set by default, which you can check by inspecting the CurrentVideoTypeFilter property.

One of your first tasks when writing these tests is to instantiate the VideosListPresentationModel class. The snippet below shows the signature of the class’s constructor:

public VideosListPresentationModel(   IVideosListView view, IVideoRepository repository){   ...}

The constructor’s signature tells you that the class expects two dependencies to be injected into it: a view and a repository, of types IVideosListView and IVideoRepository, respectively. The parameters are typed as interfaces, so you can use any object that implements those interfaces. Besides abiding by the Dependency Inversion Principle (by making the class depend on abstractions, instead of concretions), this approach also helps with testability, since you don’t need to pass in the real implementation of those dependencies when writing the unit tests.

You saw a class that implements IVideosListView earlier in this article: the VideosListView class. You may be thinking “Ah, so I could instantiate that class and pass it into the presentation model, couldn’t I?

Yes, you could, but what if that class had some bugs that could interfere with your tests on the presentation model class? That’d be bad; unit tests shouldn’t fail because of defects of a class’s dependencies.

But that VideosListView class seemed so simple; what could possibly go wrong?” The answer is: quite a few things.

For instance, there could be some problem with the XAML that prevents the class from being instantiated (a simple resource dictionary that can’t be found during run time would do it). Or maybe the window uses a third-party control for which you only have a trial version; a nag screen pops up whenever the window gets instantiated. You certainly don’t want a nag screen showing up when you run your tests.

Author’s Note: Of course, there’s a lot more that could go wrong, but these examples sprang to mind first, because they happened to me recently!

What about that “repository” parameter? In this scenario, that object’s responsibility is to provide data to the presentation model (some people may jump at me saying that I should use a domain service instead of a repository, but bear with me; this is just a simple example).

The presentation model has no business knowing how the repository obtains the data (it could be using a database, an Object-Relation Mapper framework, or reading the data from an XML file somewhere). Further, anything that goes wrong with the repository should not interfere with your tests on the presentation model.

Think about it: there are a lot of things that can go wrong when you try to retrieve data from a database, for instance. Besides, even if the test could get to the database, you’d be violating two best practices for unit tests: you’d be accessing an external resource, and you’d be causing the test to run slowly (because connecting to a database and retrieving data is a slow process by nature).

By now you’ve established you can’t use the VideosListView class. So what do you do? Remember the constructor expects any object that implements the IVideosListView interface? You could pass in a fake object; a stub that looks like the real one, but doesn’t really do anything. The same solution applies to the repository.

Using Static Fake Objects

A static stub for IVideosListView is nothing more than a class statically defined by the developer. Such a class has just enough implementation code to satisfy the compiler:

public class StubView : IVideosListView{   public IVideosListPresentationModel Model    { get; set; }   public void Show()   {}   public event EventHandler       ShowVideoDetailsRequested;   public event EventHandler        VideoListRequested;}

Notice in the preceding code that the Model property is an auto-implemented property (therefore providing the minimal behavior for a property), the Show method doesn’t have any implementation code, and the two events, ShowVideoDetailsRequested and VideoListRequested, are declared but there’s nothing handling them.

A static stub is nothing more than a class statically defined by the developer.

The code below shows a similar stub class implementation for IVideoRepository:

public class StubRepository : IVideoRepository{   public IEnumerable

At this point you’re ready to start writing your tests. Remember, the first tests you’re going to write check the expectations on the presentation model for its initial state. You start the test class as follows:

[TestClass]public class    VideosListPresentationModel_InitialState_Tests{   private static VideosListPresentationModel PM;   private static StubView View;   private static StubRepository Repository;   [ClassInitialize()]   public static void FixtureSetup(TestContext tc)   {       View = new StubView();       Repository = new StubRepository();       PM = new VideosListPresentationModel(View,           Repository);   }}
Author’s Note: Notice that I use a FixtureSetup method (which runs before all tests within the test class are run) to instantiate both the stub classes as well as the presentation model.

Next, write the tests according to the expectations you had outlined earlier (the name of the test methods should remind you of what those expectations are):

[TestMethod]public void Should_set_view_to_View_property(){Assert.AreEqual(View, PM.View); }[TestMethod]public void Should_set_model_for_given_view(){Assert.AreEqual(PM, View.Model);}[TestMethod]public void Should_default_to_NoFilter(){Assert.AreEqual("(No Filter)",    PM.CurrentVideoTypeFilter);}

These tests all fail because the behaviors aren’t implemented on the presentation model yet (which is good Test-Driven Development practice). Go ahead and implement the constructor on the presentation model class:

public VideosListPresentationModel(   IVideosListView view,      IVideoRepository repository){   m_Repository = repository;   View = view;   View.Model = this;   CurrentVideoTypeFilter = "(No Filter)";}

You’ve implemented a few unit tests for the VideosListPresentationModel class, and you’re testing only the class’s implementation, without having to worry about the real implementation of its dependencies (in this case, the view and the repository). Move on to the next batch of tests.

In the sample application scenario, a user may get a list of videos using the user interface by selecting a video type as the filter, or selecting “No Filter”, and then clicking “Get Videos.”

Clicking the “Get Videos” button raises the VideoListRequested event, passing the selected filter. The presentation model is then responsible for handling the event, populating its VideosList collection property, which the ListView control on the view is bound to. There are three expectations you need to test:

  • The CurrentVideoTypeFilter property on the presentation model should be set to the filter requested by the user.
  • When the user specifies “(No Filter),” the VideosList property should contain all the available videos.
  • When the user specifies a video type as the filter, the VideosList property should contain only videos that satisfy that filter.

Because this set of presentation model tests requires a different context, create a new test class for it. Doing so makes the intent of your tests clearer, and prevents you from falling into the anti-pattern trap of creating one test class per SUT. Note however that this article is about mocks and stubs, and not about best practices on writing and organizing tests. To learn more about the latter, I recommend you take a look into the Behavior-Driven Development style of tests (check out Scott Belware’s article on the subject in the May/June 2008 issue of CoDe Magazine).

The test class for this context would initially look pretty much like the one you created before, with the stubs and presentation model being instantiated in a FixtureSetup method. However, things start to get a little more complicated here. First, you need to find a way to raise the VideoListRequested event on the view (since that’s what happens when the user triggers that action on the UI). You certainly don’t want to pop up a UI, and then click a button for that. Instead, you can change the StubView class you created previously, adding a method to it that can raise that event for you:

public void RaiseVideoListRequestedEvent(   string filter){   VideoListRequested(this,       new VideoListRequestedEventArgs(filter));}

Getting Sample Data

Next, you know that the presentation model must get the data somewhere, and you've established it uses the repository object for that. Therefore, you must provide your StubRepository object with some sample data. Add the following lines of code to that stub class:

private List

Nothing special going on there: the SetFakeData method lets you feed some data into the repository so it can give the data to the presentation model when requested. Remember that this is used only by your unit tests; normally the repository is likely to get that data from a database or something similar.

But wait, you have not implemented any querying methods on your StubRepository, so you must do that too:

public IEnumerable

As you can see, the querying methods are trivial: GetAllVideos simply returns the list you'll send to SetFakeData, and GetAllVideosOfType will return items that match the given criteria. You write as little code as possible.

With those changes in place, you can adjust the FixtureSetup in your new test class as follows:

[ClassInitialize()]public static void FixtureSetup(TestContext tc){   // unchanged code elided   m_ListOfVideos = new List

Note that you're simply creating some arbitrary set of test data, and feeding that to the stub repository using the SetFakeData method.

Now you can write the tests. The first test checks whether the CurrentVideoTypeFilter property gets set to the filter passed to the event:

[TestMethod]public void Should_set_current_filter_to_requested_filter(){   string filter = VideoType.Dvd.ToString();   Assert.AreNotEqual(filter,       PM.CurrentVideoTypeFilter);   View.RaiseVideoListRequestedEvent(filter);   Assert.AreEqual(filter,       PM.CurrentVideoTypeFilter);}

Next, you test to see if the VideosList property gets populated with all the videos when the event gets raised with filter set to "no filter":

[TestMethod]public void Should_retrieve_all_videos_if_no_filter_spec(){   View.RaiseVideoListRequestedEvent(      "(No Filter)");   Assert.AreEqual(m_ListOfVideos.Count,       PM.VideosList.Count);}

Finally, test to make sure that VideosList gets populated with only the videos that satisfy the requested filter:

[TestMethod]public void Should_retrieve_only_videos_for_specified_filter(){   View.RaiseVideoListRequestedEvent(      VideoType.BluRay.ToString());   Assert.AreEqual(1, PM.VideosList.Count);   Assert.AreEqual("Video 1",         PM.VideosList[0].Title);}
It'd be great to be able to create fake objects dynamically as you need them, and that's where a mock framework comes in handy.

Listing 1 contains the parts of VideosListPresentationModel that are relevant to the last three tests you've just created. I've hooked up the event handler for the VideoListRequested event in the class's constructor. The handler updates the CurrentVideoTypeFilter property, and calls either GetAllVideos or GetAllVideosOfType methods on the repository, depending on whether the user specified a filter; in either case, the code returned results in the VideosList property.

Considerations on Static Fake Objects

For the six tests you've written so far, you've created two static fake classes: StubView and StubRepository. You should recall that for the first three tests (the ones validating the initial state behavior of the presentation model), you created the fake classes with the bare minimum implementation. However, for the second set of tests (the ones that validate the list retrieval behavior) you've had to make changes to those fake classes, to fit the context for the tests.

What if the changes you've made to support the second set of tests had broken the first set of tests? That wouldn't be good. And what if, in order to write the remaining tests for this presentation model, you have to make even more changes to the fake classes? You could end up adding if blocks, switch blocks, or more things of that sort to support the different contexts for different tests. That would turn your fake classes into a big mess, and you don't want that.

Another possibility would be to create one set of fake classes for each specific context required by your tests, which could also turn into a maintenance nightmare.

Wouldn't it be nice to just use some sort of framework where when you can simply request an object that implements an interface, and specify the results to return for any specific method? In other words, it'd be great to be able to create fake objects dynamically as you need them. That's where a mock framework comes in handy.

Using Dynamic Fake Objects

There are several frameworks out there (often referred to as "mock frameworks"), both commercial and free, that will create dynamic fake objects for you. The more popular free ones are Rhino Mocks and MOQ, while TypeMock is a popular commercial version. While all the frameworks provide similar kinds of features, they're implemented differently. I'll use Rhino Mocks in this article to rewrite the tests you've seen so far. You can go ahead and get rid of both the StubView and StubRepository classes.

Go back to the VideosListPresentationModel_InitialStates_Tests test class and make a few changes to it. That class originally had fields to store references to your stub view and repository objects:

private static StubView View;private static StubRepository Repository;

Because you don't have those fake classes any more, you need to change the types of those fields to their respective interface types:

private static IVideosListView View;private static IVideoRepository Repository;

Next, you need to change the code where you were assigning instances of those fake classes to those fields. Use Rhino Mock's MockRepository's GenerateStub method to create dynamic mocks for those interfaces. The MockRepository class exists under the Rhino.Mocks namespace:

[ClassInitialize()]public static void FixtureSetup(TestContext tc){   View = MockRepository.GenerateStub();   Repository = MockRepository.GenerateStub();   PM = new VideosListPresentationModel(      View, Repository);}

Rhino creates a dynamic class at run time that provides a minimal implementation (very similar to the classes you had created before, except that you don't need to maintain individual classes yourself).

Those are the only changes you need to incorporate Rhino Mocks into the tests. You should be able to run the tests and see they all pass.

Now off to the other three tests you wrote; the ones testing the retrieval behavior for the list of videos. Remember, you needed to add more code to your fake classes to support those tests. First, you had to add a method to the StubView class so you could raise the VideoListRequested event on the view:

public void RaiseVideoListRequestedEvent(string filter){   VideoListRequested(this,       new VideoListRequestedEventArgs(filter));}

You also added a SetFakeData method to the StubRepository class so you could feed it some test data:

private List

Finally, you had to implement methods on the StubRepository class to retrieve the lists of videos:

public IEnumerable

You can now rewrite these tests, leveraging the possibilities Rhino Mocks gives you.

As you've done before, get rid of the references to both StubView and StubRepository, and replace those with references to their respective interfaces. You use the MockRepository.GenerateStub() method as you did before. Nothing new so far.

You can remove the call to SetFakeData, because you don't have an object with that method anymore:

[ClassInitialize()]public static void FixtureSetup(TestContext tc){   // unchanged code elided   // This is no longer necessary!   // Repository.SetFakeData(m_ListOfVideos);}

The Should_set_current_filter_to_requested_filter test requires a simple change; instead of calling a RaiseVideoListRequestedEvent method, you raise the event by using a feature of Rhino Mocks that allows you to raise events on an object:

[TestMethod]public void    Should_set_current_filter_to_requested_filter(){   string filter = VideoType.Dvd.ToString();   Assert.AreNotEqual(filter,        PM.CurrentVideoTypeFilter);   View.GetEventRaiser(x => x.VideoListRequested += null)      .Raise(null, new VideoListRequestedEventArgs(filter));   Assert.AreEqual(filter,        PM.CurrentVideoTypeFilter);}

By importing the Rhino.Mocks namespace to the current source file, you get several extension methods, free of charge, that help you when writing your tests. One is the GetEventRaiser method. That method as an argument a lambda expression containing the expression used to wire up an event:

x => x.VideoListRequested += null

You assign null to the event because you don't really need to handle that event here. GetEventRaiser returns an IEventRaiser object, which in turn has a Raise method. You then call Raise, passing in whatever parameters are necessary when the event is raised. In this case, the VideoListRequested event expects a sender object, as well as a VideoListRequestedEventArgs object:

.Raise(null, new VideoListRequestedEventArgs(filter));

You're passing null as the sender because that parameter is irrelevant in this case.

Off to the Should_retrieve_all_videos_if_no_filter_spec (specified) test method. That method raises the VideoListRequested event, passing in "(No Filter)" as the filter, and then checks whether you get the correct number of videos back. The only change you need here is to use GetEventRaiser/Raise to raise the event, just as in the previous test.

The test also needs to provide the repository with some test data, because you no longer have that SetFakeData method, and the dynamic stub doesn't have any data by default. Under this scenario (the user requests a list with no filter applied), you know that the presentation model is going to call a GetAllVideos method on the repository. So you need to "stub out" that method call, making it return whatever you need to satisfy the expected context of your test. The dynamic stub gives you a Stub method that allows you to do just that:

[TestMethod]public void Should_retrieve_all_videos_if_no_filter_spec(){   Repository.Stub(x => x.GetAllVideos())      .Return(m_ListOfVideos);   // remaining code elided}

The call to the Stub method accepts a lambda expression containing your expected call to GetAllVideos, and the call to the Return method takes the object you want returned whenever that call to GetAllVideos happens. In other words, you could read that line of execution as: "Whenever GetAllVideos is called on the repository, return m_ListOfVideos."

You're done with that test, so move on to the other one: Should_retrieve_only_videos_for_specified_filter. That test raised the VideoListRequested event, passing in a specific filter (VideoType.BluRay). The changes you have to make to this test are similar to the changes you've made to the previous one: use GetEventRaiser/Raise to raise the event, and before that, stub out the call to the method on the repository that you expect the presentation model to make (in this case, GetAllVideosOfType), and return the expected test data:

VideoType filter = VideoType.BluRay;IEnumerable

State-Based and Interaction-Based Tests

At this point you may be thinking: "I thought this article was about mocks and stubs, but so far I've only seen stubs!" So it's time you have a look at mocks.

Stubs are the type of fake objects that help you with state-based testing.

Up to this point, your tests can be considered "state-based" tests: you act upon your system under test, and then you check its state to make sure it matches your expectations. The first batch of tests checked the state of the newly instantiated presentation model to answer questions such as "Does it have references set to the appropriate objects?" or, "Does it have some properties set to some specific defaults?" The second batch of tests checked the state of the presentation model, more specifically the state of its VideosList property, to make sure the list gets populated properly after the presentation model has handled an event raised by the view. Stubs are the type of fake objects that help you with state-based testing. They are either filled with values to be read by the SUT to perform its duties, or the SUT sets their values, which the test then checks.

In other situations, state-based tests aren't possible, or aren't easy to write (for example, there may not be a state to check for). This type of situation comes up when the SUT has dependencies and you need to test the interaction of the SUT with those dependencies. In such cases, you can resort to interaction-based tests. Mocks are the type of fake objects that help you with interaction-based testing. They act much like spies, watching expectations set by the test on the mock, and then reporting these expectations back to the test.

Interaction-Based Tests Using Static Fake Objects

In the sample application, the VideosListPresentationModel is responsible for showing its view when you call its ShowView method:

public void ShowView(){  View.Show();}

The ShowView method shows the view by sending a message to it; that is, it calls the view's Show method. The test for that behavior has to check for the interaction between the presentation model and its view. To write such a test using a static mock object, you need to write some code, so that whenever methods get called you flip a Boolean field to indicate that the message has been received. The test can then check the value of that field to see whether the expectation has been met.

Start by creating a static mock class that implements your IVideosListView interface:

public class MockView : IVideosListView{   public bool ShowWasCalled;   public void Show()   {      ShowWasCalled = true;   }   // other members code elided}

The important information there is that you define a Boolean ShowWasCalled property, which gets set to true by the Show method whenever that method gets called.

Your test class for that behavior looks pretty much like the ones you've created earlier in this article when you were using static stub classes, except that now you instantiate the MockView class, as opposed to the StubView class:

[TestClass]public class VideosListPresentationModel_ViewDisplay_Tests{   private static VideosListPresentationModel PM;   private static MockView View;   private static StubRepository Repository;   [ClassInitialize()]   public static void FixtureSetup(TestContext tc)   {      View = new MockView();      Repository = new StubRepository();      PM = new VideosListPresentationModel(View,          Repository);   }}

The following snippet shows the test method for that expected behavior:

[TestMethod]public void ShowView_should_display_the_view(){   PM.ShowView();   Assert.IsTrue(View.ShowWasCalled);}

Not much there: you act on the presentation model by calling its ShowView method, and you check the ShowWasCalled property on the "mock" View to make sure the message was sent to that object, thereby validating the interaction between the two objects.

So how would you write an interaction-based test using dynamic mocks?

Interaction-Based Tests Using Dynamic Fake Objects

You can rewrite the test to use dynamic fake objects (which means you can get rid of that MockView class you created in the previous section). The code snippet below highlights the main aspects of building a test class that uses dynamic fake objects:

private static VideosListPresentationModel PM;private static IVideosListView View;private static IVideoRepository Repository;[ClassInitialize()]public static void FixtureSetup(TestContext tc){   View = MockRepository.GenerateMock();   Repository = MockRepository.GenerateStub();   PM = new VideosListPresentationModel(View, Repository);}

Type both the View and Repository fields to their respective interfaces. The Repository field gets an instance of a stub generated by Rhino Mocks; whereas, the View field gets an instance of a mock generated by Rhino Mocks. I'll explain what the difference is between a stub and a mock shortly.

Here's how the test method should look now:

[TestMethod]public void ShowView_should_display_the_view(){   PM.ShowView();   View.AssertWasCalled(v => v.Show());}

AssertWasCalled is another one of those nice extension methods exposed by the Rhino.Mocks namespace. You call that method on the View to assert that a given method was called on it; in this case, the Show method. That eliminates the need to create a separate class manually, create a Boolean field, and then set that field within the method you expected to be called! Rhino Mocks takes care of inspecting the object to make sure the expected method was called.

Mocks are the type of fake objects that help you with interaction-based testing.

So what happens if you break the ShowView method, by removing the call to View.Show(). The test would then fail, and Rhino Mocks would give you the following error message:

TestCase 'VideosListPresentationModel_ViewDisplay_Tests.ShowView_should_display_the_view' failed: Rhino.Mocks.Exceptions.ExpectationViolationException: IVideosListView.Show(); Expected #1, Actual #0.

In other words, the test failed because you expected one call to IVideosListView.Show(), but didn't get any.

GenerateMock vs. GenerateStub

So what's the difference between the GenerateMock and GenerateStub methods? The dynamic objects created by both methods are very similar. The main difference is that mock objects can cause a test to fail when expectations set on it aren't met. A stub, on the other hand, won't cause a test to fail if expectations set on it aren't met.

You can learn more about these subtle differences reading the documentation on Rhino Mocks. Also make sure to read Martin Fowler's "Mocks Aren't Stubs" article.

When to Use Dynamic Fake Objects

Dynamic fake objects are not silver bullets. They certainly help in many scenarios, but may not be very helpful in others. Sometimes, configuring the dynamic mock is so hard and/or complex that it's better to just create a simple static fake object for it. It's up to the developer to analyze the situation and decide which technique will produce a test that is easier to write, understand, and maintain.

Also, there are situations where a mock framework may have limitations that can rule out its use. For example, Rhino Mock can mock only virtual members, and it cannot mock sealed classes. Many developers would argue that members should always be virtual, and mocking sealed classes shouldn't be necessary if classes have been designed properly?but you may be in a situation where you just can't afford the time or money to make changes to your design to make your classes more testable.

TypeMock (the commercial framework mentioned earlier), on the other hand, can mock pretty much everything: sealed classes, private and non-virtual members, etc. That's definitely useful when you're writing tests for a legacy code base that wasn't designed with testability in mind, and when fixing the design and implementation is out of question, but it may also spoil you, and lead you to write sloppy code.

I really don't want to dive into that discussion because a lot has already been said about it on the web. I'll leave it up to readers to research. I just wanted to briefly mention these things so you are aware of their existence.

This article covered the isolation of dependencies when writing unit tests by using fake objects. By isolating those dependencies you end up with unit tests that become more informative in case things go wrong, because you're more likely to be tracking a bug in your SUT, as opposed to tracking a bug that may stem from the SUT's dependencies. Fake objects also help the unit test to become solely a "unit" test, causing tests to run faster and be independent of outside resources such as files on disk, databases, web services, etc.

Mock frameworks help you keep your code base clean, eliminating the need to create and maintain extra individual classes for static fake objects.

You've seen some basic scenarios, the main differences between static and dynamic fake objects, as well as state-based and interaction-based tests. You've also covered a little of how to use Rhino Mocks for dynamic fake objects. To be fair, Rhino Mocks deserves an entire article that would show how to leverage the framework when writing tests for more complex behaviors.

Useful Resources

I recommend these resources as a starting point for digging more deeply into writing unit tests using mocks and stubs to isolate SUT dependencies:

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist