Mock Stub Shunt

People seem to use these words (Mock, Stub and Shunt) interchangeably, but they are different ideas. In roughly increasing order of sophistication:

Other variations:

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

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 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(&current_inputs); return current_inputs; } IO getOutputs() { readOutputs(&current_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 EmbeddedSystems. 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 UnitTests (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: -- CarltonBrown?

CategoryMockObjects CategoryTesting

View edit of October 5, 2014 or FindPage with title or text search