Mock Object

TimMackinnon, SteveFreeman and PhilipCraig? presented a paper at XP2000 on the topic of MockObjects. Similar in idea to stubs (see: MockStubShunt), mock objects take stubs to an extreme and are used to set and verify expectations on interactions with model code. We found that this approach to unit testing has the side effect of making your code conform more to the LawOfDemeter.

A Mock Object
  1. is easily created
  2. is easily set up
  3. is quick
  4. is deterministic
  5. has easily caused behaviour
  6. has no direct user interface
  7. is directly queriable

SteveFreeman and NatPryce have a website at http://www.mockobjects.com/ that, as of 2009, includes a blog, several papers by the authors, and a work-in-progress draft of a book, GrowingObjectOrientedSoftwareGuidedByTests?
When I first came across this concept, I immediately thought of the scene from the movie Twister in which the tornado-chasing team deploys into the tornado a series of aerodynamic balls, each containing complex sensors that recorded the inner workings of the tornado and relayed this data back to their computers. Having read more about Mock Objects, this seems to be a nice visualization. At least it helped me. :)

Papers

The original XpTwoThousand paper was: Endo-Testing: Unit Testing with Mock Objects, T Mackinnon, S Freeman, P Craig

Further papers from the original authors include: You can find a copy of the original paper at: (An older copy of this paper was available on okchicken.com. Please ignore this version as it was a draft copy that has been superseded by the above.)

Other papers: At XpUniverse 2001, AsimJalis and LanceKind presented GuardGenerator?, a tool for automatically generating mock objects using reflection in Java. http://www.xpuniverse.com/2001/pdfs/Testing04.pdf

Reasons to mock:
  1. real object has non-deterministic behavior
  2. real object is difficult to set up
  3. real object has behavior that is hard to cause (e.g., network error) (similar to 1)
  4. real object is slow
  5. real object has (or is) a UI
  6. test needs to query the object, but the queries are not available in the real object (e.g., "was this callback called?") (This needs a MockObject that has *more* stuff than the real object; the other cases usually require a stub that is far smaller than the real object).
  7. real object acts "normal" most of the time, but once a month (or even less often) it does something "exceptional". We want UnitTests to make sure the rest of the system does the RightThing whether or not the object is acting "normal" or "exceptional". (Is this the same as #2 ?)
  8. real object does not yet exist


Overlapping concepts: ShuntPattern, StubObject, FakeObject. See MockStubShunt for wiki's attempt to differentiate them.
"I HaveThisPattern" examples at... UnitTestDelegator, HowToTestCallsMadeByAnObject
CeePlusPlusExample

Suppose we are testing a class Zombie which collaborates with class Victim, which is hard to set up and doesn't have a query method to see if it still has brains. Let's use a method testZombieRemovesVictimsBrains to make sure that when we call Zombie 's see(Victim aVictim) method, the Victim 's brains get eaten. (Details such as construction, destruction omitted for brevity. Code is written before coffee and without being tested or paying too much attention to style, please correct mistakes, but be gentle.)

in Victim.h
 class Victim
 {
 public:
	virtual void RemoveBrains();	//made virtual for easy mocking
	// assume lots of complicated set up, etc
 }

in MockVictim.h
 class MockVictim : public Victim
 {
 public:
	MockVictim();
	virtual void RemoveBrains();
	virtual bool BrainsEaten();
 private:
	bool itsBrainsEaten;  //constructor would set this to FALSE
 }http://www.mockobjects.com/

in MockVictim.cpp
 void MockVictim::RemoveBrains()
 {
	itsBrainsEaten = TRUE;
 }

bool MockVictim::BrainsEaten() { return itsBrainsEaten; }

in TestZombie.cpp
 TestZombie::testZombieRemovesVictimsBrains()
 {
	SetUp(); //creates member objects, itsZombie and itsVictim, which is an instance of Zombie and MockVictim

//make sure that, for whatever reason, stuff isn't getting set up which already passes the test //I prefer explicitly stating whether a boolean query in a test should return FALSE or TRUE, YourMileageMayVary ASSERT(FALSE == itsVictim.BrainsEaten() );

//point out juicy brains to the Zombie itsZombie.see(itsVictim);

//make sure the Zombie actually had a meal ASSERT(TRUE == itsVictim.BrainsEaten() );

TearDown(); }

Tools to create/use MockObjects: URLs for tools etc: http://www.mockobjects.com/, http://www.jmock.org/, http://www.easymock.org/, http://www.mockmaker.org/, http://www.polygenix.com/ (DeadLink), http://sourceforge.net/projects/dotnetmock/, http://jmockit.dev.java.net/, http://www.sevenmock.org/, http://groups.yahoo.com/group/extremeprogramming-seattle/files/GuardGenerator.jar, http://mockito.org/


Discussion I will take a somewhat contrary position. All except for the final point and point 2 above are valid boundry conditions which must be dealt with. If the real object is non-deterministic find out why. Either fix it or get it fixed. If it is out of scope, have your software deal with it gracefully. Point 3 is a rehash of point 1. Point 4 should not be an issue, just let it run in a test environment over night. Point 5, I have found ways to test GUIs using Nunit, just call the correct methods after creating an object. Point 6 this is more of an integration test than a unit test (you end up testing 2 or more classes), but call the object that creates the call that creates the callback. Integration tests are useful. Point 7 is once again a rehash of points 1 and 3, software *must* deal gracefully with boundry conditions.

My fear is that instead of dealing with what the reality of the situation is you end up dealing with what you wish it was. I have frequently dealt with legacy systems where the inputs have been dirty and unexpected, so I have learned *not* to try to force what I think the situation should be onto my software. It has always bitten me in the past. You must test what you have, not what you want. Please take this as advice from someone with scar tissue. PedroLopez?

The goal here isn't to idealize boundary conditions away by having deterministic behavior. The goal is to cause the boundary conditions more frequently (e.g. have a network failure every time) to ensure they are tested.

The goal for using these to deal with nondeterministic objects is to feed the program a known value with a known answer in our tests so we can make sure the result under those conditions is correct, and not simply sensible.
re: I still can't find a good description of what a MockObject is.

I have written a blog entry about the distinction between stubs, fakes, and mock objects here: http://vladimirlevin.blogspot.com/2007/11/stubs-fakes-mocks.html

The Paper:

Can you include a description here for the benefit of those people without Adobe Acrobat? I could only find a PDF paper on the subject. -- WillSargent

There's an HTML copy on http://www.mockobjects.com

I still can't find a good description of what a MockObject is. This page doesn't have enough information for me to have a good idea (although I'm sure everyone on this page agrees that it's a wonderful idea), and the links included on this page don't work. I see ShuntPattern, but that still doesn't tell me very much unless I'm looking at a database. -- WillSargent

A MockObject is an object created to stand-in for an object that your code will be collaborating with. Your code can call methods on the MockObject, which will deliver canned results. The MockObject can also examine the arguments passed to it, or can deliver the arguments to your test code to be examined.


From the XpMailingList:

Jim - I am very surprised to hear that you have found that shunts are making your code hard to read. At XP2000 we presented a paper on MockObjects (which are the same as stubs/shunts but taken to the extreme) and one of the things we noticed was that it made our code more readable, and in fact improved the design of our code as it conformed to the Law of Demeter quite naturally.

One of the other authors of the paper (Steve Freeman) came to visit our team at Connextra and I left him with two junior programmers to have a look at the code (which he had never seen before) and 1 hour later he had spotted a number of improvements and was able to navigate the design fairly easily with the help of the others. Part of this is XP - however the other part was that he recognized the mock objects testing/formatting pattern. Although Steve didn't look at the entire system - because of the isolated testing that MockObjects encourages he was able to move to totally separate areas of the system and comment on them.

A new member of our team (second day at work) who had sat with Steve commented "My god - I feel so stupid, how can a guy walk off the street, and just pick up our code so easily". When I explained that he understood MockObjects practice he was very relieved and the next day he was doing the same thing as Steve, spotting areas for improvement etc.

MockObjects came from our desire to eliminate getters that we were writing just so that we could test code. Worse still, the getter exposed data types that were a lot of work to test because they often lost precision (e.g. a stream or a string). The inner class technique you have hit upon sounds ok - but we have found that MockObjects and the way they encourage you to compose objects to write tests make inner class testing unnecessary.

I'm not sure if this is a helpful comment for you - but thought I should chip in.

Tim


 ----- Original Message -----
 From: "Jim Little" <jiml@inconnect.com>
 To: <extremeprogramming@egroups.com>
 Sent: Friday, June 16, 2000 6:47 AM
 Subject: Re: [XP] Heresy

From: Robert Leftwich <digital@ix.net.au>

Jim Little wrote:
On a GreenfieldApplication, I designed the app for testability using shunts (aka MockObjects). Now tests are beautifully easy but the design is much harder to understand.

That worries me, which was why I raised the topic a while back. Design for testability has a marked impact on the end result. Maybe I'm just not refactoring enough or in the right places to end up with a simple design that is easy to test.

We had the opposite experience on a couple of different sites. I went to visit TimMackinnon and could see more or less immediately what the code was up to. The important points are to have conventions for the structure of the tests and to read the tests first. --SteveFreeman


I recently heard about someone who uses Java's inner classes to provide a testing interface. This seems like a beautiful idea to me since the testing interface can duck around the business rules of the class's PublicInterface. (Java inner classes can modify private instance data within their enclosing class, in case you didn't know.) This seems to me to be a much simpler approach than shunts -- the only drawback is that now your testing interface is inside your production code.

I HaveThisPattern; see NestedTestCaseClasses for a description.

I haven't tried this yet, but I'm seriously considering it. The shunt approach is giving people on my team major headaches when I introduce it to them. And even I, who wrote the whole thing, sometimes get confused as to what goes where and how. Definitely a sign of a troubled design!

I fail to see how this prevents you from having to use shunts/mocks. NestedTestCaseClasses just buy you the ability to access private data. If I have a method that takes an object as a parameter, it doesn't matter if I have access to the private fields of the class that contains that method, I still have to mock out the parameter object that I'm passing in. The mock objects that you are passing in aren't the objects that you are testing, they are the objects that interact with the object that you are testing. -- JavidJamae

I agree, sounds like a troubled design, and if you are having trouble mocking elements of it then the tests are telling you that the code smells. Make things simpler - think of different ways to do things. In our experience good code comes from good tests. -- TimMackinnon

One thing that I seem to be discovering, though, is that "the simplest thing that could possibly work" works much better when you have lots of prior design experience. I think that the "simplest thing" will be much more complex for a newbie than for an expert. Witness my botched first attempt at testable design... When I wrote it, I knew it was too complicated, but it truly was the simplest thing I could think of, and that's how I justified it.

Jim

I stumbled across this old email exchange of mine over a year later. How embarrasing! I've since come to rely on the MockObject pattern extensively. It's one of my most powerful tools for testing. Tim was right - I had problems with mock objects because my design was bad. Fortunately, we refactored it. -- JimLittle


TammoFreese has developed a fascinating small framework called EasyMock which helps to avoid writing mock classes any longer. You simply specify the mock object within your tests, and the framework will generate a dynamic proxy class behind the scenes.


At AbstraktGmbh, ChristianJunghans has developed the MockCreator, a VisualAgeJava tool that generates MockObjects. As of July 2002, the generated code is usable as a MockObject as well as a dummy. MockCreator is GPL/LGPL-licensed and available for Eclipse 2.0, Visual Age 4.0 and Command line usage (for all the other IDEs). Check http://www.abstrakt.de/mockcreator.html for details, download and documentation. -- OlafKock


Also see MockMaker - it generates source code from interfaces or classes, isn't limited to a single IDE and isn't limited to JDK>1.3. --IvanMoore


Recently, we discovered a change in our code when using TestFirstDesign and MockObjects together. It seemed that we prefer passing objects as method parameters (i.e. mocks) rather than making references to them part of our object state. (Re-engineered with JTogether there are less lines.)

Does anybody know what I mean? Does anybody care? Do you think it's good or bad? -- DierkKoenig

We also have this pattern. Mock objects tend to drive your classes into a highly compositional design with lots of little pieces and lots of interface surface. I generally regard this as a good thing. -- FrankWestphal

Thanks for the help. We feel that our methods become easier to move around, while there is a tendency in them to become "static" (we ususually mark them static if they are not using any object state). Now, although we have more lightweight classes and more flexible methods, we feel like leaving the OO route. Have you had the same effect? How do you deal with this? -- DierkKoenig

We almost always pass in the collaborators into the constructor, so most of our objects are still good OO citizens and centered around an abstraction. -- FrankWestphal

The logical solution. -- DierkKoenig

This very thing came up today in an JUnit/Mock object class that SteveFreeman and I were giving. There's ample anecdotal evidence that using mock objcts leads to more Demeter-ish code. In the class, for instance, we saw a definite move towards the object passing idioms that Frank and Dierk mention. This lead to a vast improvement to the code produced by some developers with relatively little experience. For instance, they had been writing very procedural code, with lots of logic in the methods. Using Mocks seemed to lead them more towards building networks of objects that do the right thing. -- KeithBraithwaite

I find that the mere act of adopting test-first programming pushes the programmer to write better code (not the tests themselves, the mindset of writing the tests first). If the programmer isn't aware of MockObjects, they're not likely to discover them on their own. If they are aware, then MockObjects become a very powerful tool indeed, but the drive to write better code comes from the UnitTesting, IMHO. I wonder if there's anyway to test that hypothesis... ;-)


I've found a side effect of MockObjects is that most of my methods are public, but I have a lot of private protocols between objects.


I've recently been using MockObjects for UnitTestingLegacyCode. I have not looked into EasyMock or any other framework, just coding my mocks as I go. See MockingLegacyCode for more information.


MockObject is an application of NullObject. -- BobbyWoolf

That's like saying that StrategyPattern and StatePattern are the same thing. The UML diagrams might be the same, but the intentions are different. One major difference between NullObject and MockObject is that NullObjects are typically used in the application, whereas MockObjects are used primarily for testing, and are not typically deployed.

Furthermore, my MockObjects typically return real values and track the insert/update/delete statements done to them. I would expect a NullObject to always "do nothing" and "return nothing" -- whatever "nothing" may mean in that context. -- JeffGrigg


Someone want to volunteer a SampleMockObject?? Java for preference, but any OO language acceptable.

There are several in the mock object library at http://www.mockobjects.com. The distribution includes some implementations for the standard java libraries, e.g. servlets, and some worked examples. There's a bit more in the CVS repository on SourceForge. --SteveFreeman


Are people mostly using interfaces to implement MockObjects in Java? I'm finding it's less error-prone than simply inheriting from the real object. But whenever I want to add a method I have to change it in three files: the real object, the interface, and the mock object. I wonder if there's a quicker way. Look at the guard generator tool described earlier on this page.


A nice thread on *doing* MockObject in C++: http://groups.google.com/groups?hl=en&threadm=mCQf8.16687%24tg7.335940701%40newssvr21.news.prodigy.com&prev=/groups%3Fhl%3Den%26group%3Dcomp.software.extreme-programming


Anyone tried writing mock objects in component oriented application servers (COM+, EJB's, WLE/Tuxedo)? Are you also running into trouble with a LawOfDemeter design conflicting with the design requirements for declarative transaction processing (woe unto you who expose transactional objects to others)? Perhaps my troubles are merely a special case of what happens when you wish to unit test with the underlying logic and DAO layers, but without the complications of a live database (which you otherwise must set to a known state before every automatic unit test run: quite a maintenance burden). I'd be interested in any ideas on this, as I'm reluctantly moving towards the view that designing for testing with mock objects has a much too adverse design impact on most kinds of distributed systems. Are mock objects only applicable on the very lowest level, within components? -- PontusGagge?

It sounds like you are doing integration testing, rather than unit testing. I've found MockObjects to be most useful when testing individual units (classes, or Python modules) in isolation.


In some cases, it's not possible to use an interface and extend MockObject. For example, a class I'm writing extends an application server-defined concrete class in order to use some out-of-the-box functionality like logging methods. When running unit tests, I can't use the actual superclass, as it in turn relies on systems that only exist when running in the container.

So the solution we've come up with is to write our own mock version of the superclass, and define it in a different classpath (the "mock classpath"). In that class, we implement mock versions of the required methods. Then, when we run the tests, we add the mock classpath to the beginning of the classpath, so the mock object stands in for the real object at test time. Does this seem like a valid solution? How have others dealt with this problem?

For example:

  // GenericService is defined by the application server
  public class GenericService {
	public void logError(String errorMessage) {
	...
	}
  }

public class MyCustomService extends GenericService { public void methodBeingTested() { // do something // log an error logError("something went wrong"); } }

// mock GenericService class public class GenericService extends MockObject { public void logError(String errorMessage) {} }
-- RodrigoPalacios? and ChristopherPickslay


Moved from WhichFactory

This is probably not a great page name, but I'm starting with a specific problem so I'll describe it in a specific way. I hope this can be generalized, later.


The situation

Various low-level bits of code need to share a connection to a database. These bits can get this connection from a static method, a singleton, or a factory method. In any event, they typically have to know the class to call to get this connection.

But, I want to provide a mock connection for testing purposes. If the low-level classes are calling a particular static method, retrieving a particular singleton, or calling a particular factory method, I can't substitute my mock object.

I've thought of a bunch of different things, but I'm not real happy with any of them. I've asked others here, but not gotten anywhere. (They're doing their testing with real database; I want to isolate my testing from that.)

So, how do you approach this problem?

P.S. My current implementation, to get past AnalysisParalysis, is to have a constructor that takes a factory object, for testing, and a default constructor that uses the normal factory object, for ease in the actual application. I think this has a faint CodeSmell.

I haven't tried MockObject on a DB yet, but here's something off the top of my head. Create a class called DataBaseAccessor, which has a static method getDataBase, which returns an object of abstract class DataBase. Create your real DataBase class as a subclass of DataBase, say RealDataBase for lack of context. Create another (MockObject) database class by subclassing DataBase again, say MockDataBase. The real one works like the real database, the mock one does whatever you tell it to do for the purposes of the test. Some things you might want the mock to do: Count accesses, hold onto the connection string for later comparison, set up a fake query result which you expect the testee to retrieve, etc.

That's basically what I'm doing. In fact, I'm using the MockObject project to create the MockConnection to the database (though I'm thinking about looking into EasyMock as an alternative). This is what my MockConnectionFactory returns, whereas the default connection factory returns a real database connection to the real database. It bothers me that I have a constructor in the production code that is only used for testing, not for the production code. But it bothers me less than the alternatives I considered.

I have this problem as well. The approach I'm playing with right now is to do the test via a custom ClassLoader, so that when the unit under test tries to find the database class the class loader interferes and substitutes your mock class. An example of this technique can be found here: http://www.jroller.com/page/fdiotalevi/20031112.

See also MockDatabase.

I'm currently using MockObjects extensively to test a transaction framework. I've resolved the 'constructor' problem by using factories reading the appropriate class from a configuration file. -- MarkAddleman


On another Web page, someone stated that it was a smell to create setters just to be able to inject mock objects (and thereby breaking encapsulation). I last did something "smelly" like that, only I used conditional compilation to keep the setter out of the production code. The method is an accessor to a central, company-wide list of projects. I want to be able to replace it only when testing. I'm still confused if this is too smelly or not. Does anyone have an opinion about that? -- WillemBogaerts

What I'd do in that situation is remove the setter since it's only used for testing. Instead I'd encapsulate all uses of the list of projects behind a method getProjects. Then in the test I'd override that method in an anonymous sub-class and use that for testing. See http://www-106.ibm.com/developerworks/java/library/j-mocktest.html for more info. -- AdewaleOshineye


The technique works just as well in a "stateless" application, such as with asp.net pages, as in any other. As long as you write object oriented code, in which objects collaborate to perform application tasks, mock objects are a good design aid.


Any experience using an ObjectMother? -- DavidEscala, PeterSchuh

Yes. A project I worked on started using the ObjectMother pattern quite extensively. After about four months we decided it ws causing more problems than it solved and started refactoring it out. The biggest issue was that it seemed to encourage constructing quite elaborate stand-in object networks (i.e. one ObjectMother called another, called another, etc.). In most cases, these stand-in networks contained mostly unnecessary code to the object-under-test, which made the test cases less clear (i.e the stand-in objects did not implement just the capabilities needed by the objut-under-test, but included considerable extranous code included by the ObjectMother(s)). Our replacement was a hyper-lightweight concept we called PseudoClasses. -- GeoffSobering
Isn't Mock Objects duplication or parallel hierarchy?

No. A mock object implements an interface. You typically don't have a hierarchy of interface types.

Isn't it danger to use Mock Objects in dynamic typing languages?

No. Quite the opposite. The Mock Objects technique is easier to apply in dynamically typed languages.


Does anyone have any good methods for doing mock objects in C++? It seems that the typical method would be to use a pure virtual base class / interface, and derive both the real implementation and the mock from it. But what if I can't actually use an interface (the code is too low-level and performance critical, I'd incur much wrath if I started adding runtime overhead for something which is just a debug feature).

While I appreciate your input, you've completely missed my point - adding extra overhead is non-negotiable. Other people set the rules, I just have to follow them. Around here virtual functions are frowned upon, templates are banned and exceptions are taboo. Even namespaces are viewed with mistrust (which is particularly odd given that we all know it has no actual runtime overhead).

On further thought it becomes very apparent that we're basically coding in C with operator overloading (and singletons instead of globals, but thats a rant for another day). So I guess my question becomes, how can you do unit testing and/or mocking of legacy code in a procedural language?


Somewhat re-iterating the last question here; I need to use a MockObject, but I'm struggling with the implimentation a bit. Let's say I'm writting a UnitTest for class Monkey. As part of Monkeys operation, it MUST create an instance of class Banana (ignore the poor analogy). Banana does something which I don't really want to happen during the unit test.

Obviously I need to write a Mock implimentation of Banana, and theres two ways I've tried this: The first way appears to be the nicest, however it doesnt work in this situation. Monkey constructs a Banana, not a MockBanana. Therefore, the only way it could work is if I made a BananaFactory, that would construct either a Banana or a MockBanana. This is yet more superfluous code to impose on the program, and it also affects the runtime behaviour of Monkey.

Is there a correct way to do this? - MikeAinsworth?

It's difficult with the analogy to see why Monkey should at all be responsible for Banana's construction. If Banana is too "heavy" to be used during a unit test, that would imply to me that it should be inheriting from an interface. It's a conclusion based off very little information (none) on what Monkey and Banana are actually doing. That being said, worrying about vtables and superfluous code is nonsense. Testable code does not come for free. --PatrickMcCormick?


I have to create a series of Java unit tests for existing classes (no TDD here yet) and what seems natureal to me is to create mocks by hand by creating an interface and making both the real class and the mock class implement said interface.

Obviously I want the mock class and the unit tests to stay in different jar files than the real code so that I don't release unit tests nor mock objects to the customer. Reasonable so far, isn't it?

The only problem I have is that I need a factory to decide if I'm doing a unit test or I'm running production code, so that whenever said object is instantiated, the appropiate object (real or mock) is instantiated. What I really want to test is another object, this one has to be mocked in order to test the other one (that's the theory of mocks).

The problem I have is that the tests classes have access to the real classes, but the real classes can't have access to unit tests or mock objects. Reasonable, isn't it?

And the real classes have to have access to the factories, which have to have access to both the real and the mock objects. So I'm in a conundrum. -- AnonymousDonor
CategoryMockObjects CategoryComparisons CategoryTesting

EditText of this page (last edited May 25, 2011) or FindPage with title or text search