People seem to use these words (Mock, Stub and Shunt) interchangeably, but they are different ideas. In roughly increasing order of sophistication: * '''PseudoPattern''' - A class implements an interface and throws a runtime exception in every single method. This can be a useful parent class to extend from to create Stub/Fake/MockObject''''''s. * '''StubObject''' - An implementation of an interface that returns hard-coded values. Stubs don't capture or care about state in the way that MockObject''''''s do. Stubs are used more frequently in InteractionBasedUnitTesting. * '''ShuntPattern''' - An object that implements an interface, with some minimal sophistication for testing. One might have a "Shunt Data Base" in which ''Select '''var1''' from '''var2''' '' always returns two records. * '''FakeObject''' - A class with methods that return a fixed value or values that can either be hardcoded or set programmatically. (from DaveAstels's TestDrivenDevelopmentaPracticalGuide) * '''MockObject''' - An object which, in addition to implementing the interface (like a Shunt/Stub) and returning meaningful values (like a Fake), allows for verification that the correct calls were made upon the object, perhaps in the correct order. Mocks are used more often in StateBasedUnitTesting. Other variations: * '''SelfShuntPattern''' - The test itself implements the interface of an object being used by the object under test. * '''ShamObject''' - like a Mock, but verification that the correct calls are made happens ''after'' the interaction with the object is complete. (Most Mocks fail as soon as some expectation is violated.) (common usage at RoleModelSoftware) ---- The need for clarification of arbitrary terms suggests a problem with the terminology. Perhaps the definitions are too specific? Or the names are too generic? Or perhaps the natural meanings of the terms just don't fit the application? This is an ongoing problem. So perhaps we could at least prefix the names with Test to qualify the namespace rather than polluting the generic? If we change the generics then we are generating jargon. Jargon is not a good thing IMO. ---- The terminology hasn't really settled down yet. I think the natural meanings are a good fit for "shunt", "stub", and "fake". "Mock" doesn't really convey the essence of Mock Objects: checking to see that expected calls took place. But it's so established that there's no point trying to change it. Likewise, "sham"'s natural meaning is indistinguishable from "mock"'s (outside the realm of bedding, anyway), but there's a legitimate need for a term that distinguishes fail-fast from fail-late testing thingies. Finally, it would be nice to have a generic term for the above taxonomy. "Testing Objects", perhaps? (I note that on Wiki, at least, they're all lumped under "CategoryMockObjects".) -- GeorgePaci On this site, they call them Test Doubles (and compare them to stunt doubles in movies). --Erwin *** http://xunitpatterns.com/Test%20Double.html ---- In MartinFowler's article "Mocks Aren't Stubs" he uses the word "stub" to refer to what is called a "shunt". That seems OK to me; I don't see the value in having a separate name for what's called a "stub". -- BrettNeumeier *** http://www.martinfowler.com/articles/mocksArentStubs.html It's useful if you want to understand what people are talking about when they say "shunt". Granted, I only use "shunt" instead of "stub" when talking about the SelfShuntPattern -- which isn't often. Maybe "shunt" is an Electrical Engineering thing. -- GeorgePaci (From AlistairCockburn's comment in HexagonalArchitecture: ''It is very often I need to start the day with a canned piece of data, instead of a link to a live database. In basic electronics design, they call this a "LoopBack" (what I erroneously called the ShuntPattern for a long time) - a little wire that goes out the out port and into the in port, so the machine talks to itself instead of to another machine. That shunt puts the whole communicating system on the desk of the developer, where (s)he can poke at it. How I wish our 18-month project with constantly changing persistence layer and relational database had a shunt, so we could write our own test data locally!'') ---- For some embedded plant control systems, I've used a framework with the same purpose as a hardware shunt, but much more flexible as a result of being implemented in software (CeeLanguage). The application-layer I/O API looked something like this: IO getInputs(); IO getOutputs(); void setInputs(IO newInputs); void setOutputs(IO newOutputs); The implementation of this API was the same in all configurations, something like (simplified pseudocode): // configuration-dependent extern void writeInputs(IO inputs); extern void writeOutputs(IO outputs); extern void readInputs(IO *inputs); extern void readOutputs(IO *outputs); IO current_inputs; IO current_outputs; IO getInputs() { readInputs(¤t_inputs); return current_inputs; } IO getOutputs() { readOutputs(¤t_outputs); return current_outputs; } void setInputs(IO newInputs) { writeInputs(current_inputs = newInputs); } void setOutputs(IO newOutputs) { writeOutputs(current_outputs = newOutputs); } except that subsets of I/O could be controlled independently. One implementation of the read/write functions was connected to the real hardware, another was connected to a UserInterface that displayed and could modify the current I/O state. (The framework was implemented both for a PeeCee and for the EmbeddedSystem, and the UserInterface was available whenever it was run on the PeeCee.) There was also a simulator process that could run concurrently with the application, but with no direct calls between them. The simulator would pretend to be the RealWorld, using only getOutputs and setInputs. The reason for doing it this way was that you could run the software in at least four configurations: connected either to the hardware or to the UserInterface, and with or without the simulator running (actually, with different subsets of behaviour simulated). Things that were too complicated to simulate programmatically could still be simulated manually via the UserInterface. The same framework was used (and is still running) in several different EmbeddedSystem''''''s. Each system had its own simulator, but the framework and UserInterface didn't need to be changed, apart from normal maintenance. In all of the systems a fairly simple-minded simulator, combined with the manual UserInterface, could test the application well enough that almost all software debugging could be done before the hardware was built. Based just on a few instances where it shortened '''very''' expensive periods of downtime, this framework must have paid for the effort required to write it > 10 times over. This is obviously related to ShuntPattern and MockObject, but what would you call it? Unlike MockObject, an essential part of the design was that the simulator and application never called each other directly, and only communicated via the I/O state. There was also no testing to make sure that expected calls took place; we didn't do XP-style UnitTest''''''s (and didn't miss them). -- DavidSarahHopwood ---- Perhaps the most common example of SelfShuntPattern is StrutsTest. You set up the test instance with the input data, and the action under test calls the test instance itself. ---- Some thoughts on the differences between these objects: * MockObject - has realistic data, state, and behavior, but may omit aspects uninterested to routine testing. May have additional instrumentation and diagnostic methods for testing. Purpose: Faithfully tests that agents can interact with the object and are following the correct protocol. Analogy: Flight simulator. Successfully processes user decisions and retains state. Has extra instrumentation and archiving not present in an actual airplane, but lacks actual engines and thus cannot really fly. * FakeObject - fully realistic, neither adding nor omitting data or behavior, but holds minimal state (if any). Purpose: Tests that agents can examine and react to the object as expected. Analogy: Fake security camera. Produces a set of authentic reactions in observers (avoidance, obedience, or defiance) in spite of having no actual state. * ShuntObject - has the ability to show realistic behavior and return the minimum subset of realistic data that is interesting to the test. Purpose: Surrogate for objects expensive setup or behavior that is not naturally reliable for testing purposes. Suggested uses: Databases, hardware, network connections. Analogy: Tire rollers in a car emissions testing center allow the vehicle to be exercised at highway speed without the inconvenience of instrumenting the gas cap at highway speed. -- CarltonBrown ---- CategoryMockObjects CategoryTesting