What's the difference between a mock & stub?
Asked Answered
U

42

1379

I've read various articles about mocking vs stubbing in testing, including Martin Fowler's Mocks Aren't Stubs, but still don't understand the difference.

Uriiah answered 11/8, 2010 at 14:19 Comment(7)
possible duplicate of An overview of unit testing terminology ( stub vs mock , integration vs. interaction )?, whats-the-difference-between-faking-mocking-and-stubbingMurrah
@OP Because there is no difference. This article, as much as loved by the community, is - with all due respect - making everything unnecessary confusing by adding additional meaning to words that are easy to understand otherwise and by making things unnecessary complicated. Mock is just a mock, something that runs fake business logic instead of real one. Checking for behavior in the end is your choice, but it is still a mock. Or whatever you want to call it, but make it ONE. Do not split a hairs. Keep it simple, so people can understand your concept easily - which above article does fail with.Footlights
"Classification between mocks, fakes, and stubs is highly inconsistent across the literature." With many citations. Still one of my favorite Wikipedia quotes - if such a thing exists :) en.wikipedia.org/wiki/Mock_objectTransship
that Martin Fowler's article is really hard to understand for beginners.Aeromarine
Possible duplicate of What's the difference between faking, mocking, and stubbing?Chape
The way i understand it is that a stub would just be a throw away object for your test, like a collection of dummy data. A Mock would be a cleverly overridden version of something more complex, like a service layer with various methods, which you might have changed the behavior of, for your tests. The two things are used together, like you could pass some stubbed objects into your mocked layer.Lati
@Footlights "mock is a mock" loses the argument on the spot. Mock = behavior expectation, stub is just a fixture. "I expect behavior X to have happened" is a mock. A stub is not a condition. A fake string it not a condition. Calling everything a Mock is like calling everything a Helper function.Chrysalid
E
933

Stub

I believe the biggest distinction is that a stub you have already written with predetermined behavior. So you would have a class that implements the dependency (abstract class or interface most likely) you are faking for testing purposes and the methods would just be stubbed out with set responses. They would not do anything fancy and you would have already written the stubbed code for it outside of your test.

Mock

A mock is something that as part of your test you have to setup with your expectations. A mock is not setup in a predetermined way so you have code that does it in your test. Mocks in a way are determined at runtime since the code that sets the expectations has to run before they do anything.

Difference between Mocks and Stubs

Tests written with mocks usually follow an initialize -> set expectations -> exercise -> verify pattern to testing. While the pre-written stub would follow an initialize -> exercise -> verify.

Similarity between Mocks and Stubs

The purpose of both is to eliminate testing all the dependencies of a class or function so your tests are more focused and simpler in what they are trying to prove.

Equalitarian answered 11/8, 2010 at 14:38 Comment(3)
One confusing line - A mock is something that as part of your test you have to setup with your expectations. A mock is not setup in a predetermined way so you have code that does it in your test. So, it's set up according to your expectations, but not in a predetermined way? How is that possible?Reseda
Your definition of stub is matching definition of fake in @RyszardDżegan s answer IMOToadstool
@Reseda based on other answers and from my experience, i would say that the stub is predetermined in compile-time, while a mock is determined during runtime (by setting up expectations inside the test).Geologize
B
1170

Foreword

There are several definitions of objects, that are not real. The general term is test double. This term encompasses: dummy, fake, stub, mock.

Reference

According to Martin Fowler's article:

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
  • Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Style

Mocks vs Stubs = Behavioral testing vs State testing

Principle

According to the principle of Test only one thing per test, there may be several stubs in one test, but generally there is only one mock.

Lifecycle

Test lifecycle with stubs:

  1. Setup - Prepare object that is being tested and its stubs collaborators.
  2. Exercise - Test the functionality.
  3. Verify state - Use asserts to check object's state.
  4. Teardown - Clean up resources.

Test lifecycle with mocks:

  1. Setup data - Prepare object that is being tested.
  2. Setup expectations - Prepare expectations in mock that is being used by primary object.
  3. Exercise - Test the functionality.
  4. Verify expectations - Verify that correct methods has been invoked in mock.
  5. Verify state - Use asserts to check object's state.
  6. Teardown - Clean up resources.

Summary

Both mocks and stubs testing give an answer for the question: What is the result?

Testing with mocks are also interested in: How the result has been achieved?

Bibliomania answered 23/7, 2013 at 12:18 Comment(5)
Wait, mocks also return canned answers? Cause otherwise why do they answer the question?Polyandrous
From what you wrote I can tell that mocks = stubs + expectations and verifications, because mocks "provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test" (same as stubs). And example that Fowler showed as example of a stub is actually example of a spy! That means that a mock is a stub, and a spy is a stub. And a stub is just an object that have several working methods. That also explains why Mockito deprecated stub() method.King
What I find confusing abou this and the accepted answer is this “expectation setting”, what does it even mean? Usually, in the “main code” you create the results that you would expect. It sounds like you put the expectations somehow INTO the mock object, though, which does not make sense to me. ALSO, you could just as easily exercise the mock with some input, store the result, create “the expectations” later and then compare. You use terminology that I find too abstract and ambiguous.Frostbitten
Why does this answer appear on the second page? It should have appeared after the accepted answer (if not before it). The best answer I see here, detailed, precise, and understandable.Philomenaphiloo
I think the "principle" section is incorrect. Test doubles are replacing the "collaborators", or "dependencies". There might be several of these in a test, and that's just fine. It's the System Under Test (SUT) of which there should be only one, and there is no difference here. Both Mock and Classical style testing prefer one SUT.Fulani
E
933

Stub

I believe the biggest distinction is that a stub you have already written with predetermined behavior. So you would have a class that implements the dependency (abstract class or interface most likely) you are faking for testing purposes and the methods would just be stubbed out with set responses. They would not do anything fancy and you would have already written the stubbed code for it outside of your test.

Mock

A mock is something that as part of your test you have to setup with your expectations. A mock is not setup in a predetermined way so you have code that does it in your test. Mocks in a way are determined at runtime since the code that sets the expectations has to run before they do anything.

Difference between Mocks and Stubs

Tests written with mocks usually follow an initialize -> set expectations -> exercise -> verify pattern to testing. While the pre-written stub would follow an initialize -> exercise -> verify.

Similarity between Mocks and Stubs

The purpose of both is to eliminate testing all the dependencies of a class or function so your tests are more focused and simpler in what they are trying to prove.

Equalitarian answered 11/8, 2010 at 14:38 Comment(3)
One confusing line - A mock is something that as part of your test you have to setup with your expectations. A mock is not setup in a predetermined way so you have code that does it in your test. So, it's set up according to your expectations, but not in a predetermined way? How is that possible?Reseda
Your definition of stub is matching definition of fake in @RyszardDżegan s answer IMOToadstool
@Reseda based on other answers and from my experience, i would say that the stub is predetermined in compile-time, while a mock is determined during runtime (by setting up expectations inside the test).Geologize
S
552

A stub is a simple fake object. It just makes sure test runs smoothly.
A mock is a smarter stub. You verify your test passes through it.

Sperm answered 11/8, 2010 at 14:33 Comment(8)
I think this is the most succinct and spot on answer. Takeaway: a mock IS-A stub. https://mcmap.net/q/45326/-what-39-s-the-difference-between-a-mock-amp-stub is the longer version of this answer.Stoddart
I don't think a mock is a stub. Mocks are used to assert and should never return data, stubs are used to return data and should never assert.Ballistics
@Ballistics Mocks most definitely can return data or even throw an exception. They should do so in response to the params passed into them.Wace
@trenton if an object returns or throws based on data passed in then it's a fake, not a mock. Stubs test how your SUT handles receiving messages, mocks test how your SUT sends messages. Mixing up the 2 is likely to lead to bad OO design.Ballistics
Can you provide an example code of a STUB and a mock (with minimum lines of code)? ThanksJohannejohannes
I think this is great - a stub returns answers to questions. A mock also returns answers to questions (is-a stub) but it also verifies that the question was asked !!Hanson
As a memory helper, you can think of a mock as a stub + expectationsGastrula
this explanation can be a bit misleading because "fake" is the name of a different kind of test double.Fumble
K
328

Here's a description of each one followed by with real world sample.

  • Dummy - just bogus values to satisfy the API.

Example: If you're testing a method of a class which requires many mandatory parameters in a constructor which have no effect on your test, then you may create dummy objects for the purpose of creating new instances of a class.

  • Fake - create a test implementation of a class which may have a dependency on some external infrastructure. (It's good practice that your unit test does NOT actually interact with external infrastructure.)

Example: Create fake implementation for accessing a database, replace it with in-memory collection.

  • Stub - override methods to return hard-coded values, also referred to as state-based.

Example: Your test class depends on a method Calculate() taking 5 minutes to complete. Rather than wait for 5 minutes you can replace its real implementation with stub that returns hard-coded values; taking only a small fraction of the time.

  • Mock - very similar to Stub but interaction-based rather than state-based. This means you don't expect from Mock to return some value, but to assume that specific order of method calls are made.

Example: You're testing a user registration class. After calling Save, it should call SendConfirmationEmail.

Stubs and Mocks are actually sub types of Mock, both swap real implementation with test implementation, but for different, specific reasons.

Kagera answered 26/11, 2014 at 14:12 Comment(7)
1) Read the answer 2) Read blog.cleancoder.com/uncle-bob/2014/05/14/TheLittleMocker.html 3 ) Read the answer again.Gerkman
I seldom leave comments on SO, but this answers clearly deserves a thumbs up. Clear, concise and with examples. Also, thanks for sharing the post @snrSwashbuckling
"Stubs and Mocks are actually sub types of Mock" --- do you mean Stubs and Fakes?Marks
This might be helpful: xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.htmlEnlargement
"Stubs and Mocks are actually sub types of Mock". I think you meant "Stubs and Mocks are actually sub types of Fake".Enlargement
@SonerfromTheOttomanEmpire Uncle Bob's article offers very good insight and explains the difference very well, thank you very much for suggesting thisCorrect
@FernandoGabrieli, you are welcome, my pleasure.Gerkman
F
206

In the codeschool.com course, Rails Testing for Zombies, they give this definition of the terms:

Stub

For replacing a method with code that returns a specified result.

Mock

A stub with an assertion that the method gets called.

So as Sean Copenhaver described in his answer, the difference is that mocks set expectations (i.e. make assertions, about whether or how they get called).

Fanatical answered 4/7, 2012 at 22:32 Comment(1)
To complement Dillon post, think about this, you have a Class called "MakeACake" who take several libraries: Milk, Eggs, Sugar, Oven.Majestic
S
180

Stubs don't fail your tests, mock can.

Salzhauer answered 18/4, 2012 at 20:5 Comment(2)
And I think this is good, you know if tests have the same behavior after refactoring.Rookery
@Rookery I have same feeling. As with Mock, with any changes in production code - you have corresponding changes to test code. Which is pain! With Stubs, It feels like you keep testing the behavior so no micro changes need to made with test code.Shemeka
R
129

Reading all the explanations above, let me try to condense:

  • Stub: a dummy piece of code that lets the test run, but you don't care what happens to it. Substitutes for real working code.
  • Mock: a dummy piece of code that you verify is called correctly as part of the test. Substitutes for real working code.
  • Spy: a dummy piece of code that intercepts and verifies some calls to real working code, avoiding the need to substitute all the real code.
Rollerskate answered 25/11, 2014 at 20:59 Comment(5)
Good answer. Mock sounds quite similar to Spy though, based on your definition. Would be nice if you updated your answer to include a few more test doubles.Cosgrove
This is quite good answer without blurring the picture.Elope
@Rollerskate Great answer. It would be helpful if you could update the answer and provide a clearer explanation/summary about Stub.Sling
Thanks for the suggestion; I thought it also applied to mock, so I incorporated your suggestion and did some other tweaks.Repress
#1 result on Google for "stub vs mock". Way to go @O'Rooney!Tessitura
D
95

I think the simplest and clearer answer about this question is given from Roy Osherove in his book The art of Unit Testing (page 85)

The easiest way to tell we’re dealing with a stub is to notice that the stub can never fail the test. The asserts the test uses are always against the class under test.

On the other hand, the test will use a mock object to verify whether the test failed or not. [...]

Again, the mock object is the object we use to see if the test failed or not.

Stub and mock are both fakes.

If you are making assertions against the fake it means you are using the fake as a mock, if you are using the fake only to run the test without assertion over it you are using the fake as a stub.

Donne answered 24/8, 2015 at 14:6 Comment(1)
I wish your answer would find its way to the top. Here's R. Osherove explaining this youtu.be/fAb_OnooCsQ?t=1006.Mule
N
38

A Mock is just testing behaviour, making sure certain methods are called. A Stub is a testable version (per se) of a particular object.

What do you mean an Apple way?

Nunn answered 11/8, 2010 at 14:30 Comment(2)
"What do you mean an Apple way?" Use HelveticaLigniform
In an Apple way as opposed to in a Microsoft way :)Uriiah
S
29

If you compare it to debugging:

Stub is like making sure a method returns the correct value

Mock is like actually stepping into the method and making sure everything inside is correct before returning the correct value.

Susuable answered 8/11, 2013 at 13:29 Comment(0)
W
28

To be very clear and practical:

Stub: A class or object that implements the methods of the class/object to be faked and returns always what you want.

Example in JavaScript:

var Stub = {
   method_a: function(param_a, param_b){
      return 'This is an static result';
   }
}

Mock: The same of stub, but it adds some logic that "verifies" when a method is called so you can be sure some implementation is calling that method.

As @mLevan says imagine as an example that you're testing a user registration class. After calling Save, it should call SendConfirmationEmail.

A very stupid code Example:

var Mock = {
   calls: {
      method_a: 0
   }

   method_a: function(param_a, param_b){
     this.method_a++; 
     console.log('Mock.method_a its been called!');
   }
}
Wilfordwilfred answered 25/6, 2015 at 16:56 Comment(0)
C
28

This slide explain the main differences very good.

enter image description here

*From CSE 403 Lecture 16 , University of Washington (slide created by "Marty Stepp")

Crashland answered 5/6, 2017 at 12:19 Comment(1)
This is the more clear explanation of the diff between the two, IMO. For stub: the tester take the Stub and use it directly inside the class under test. But for Mock, the tester has to device way how the Mock object will be used. In different cases, it will behave differently. In contrast, stub is not expected to behave differently but is used as it is (meaning returning the same data whenever contacted)Shieh
L
28

Using a mental model really helped me understand this, rather than all of the explanations and articles, that didn't quite "sink in".

Imagine your kid has a glass plate on the table and he starts playing with it. Now, you're afraid it will break. So, you give him a plastic plate instead. That would be a Mock (same behavior, same interface, "softer" implementation).

Now, say you don't have the plastic replacement, so you explain "If you continue playing with it, it will break!". That's a Stub, you provided a predefined state in advance.

A Dummy would be the fork he didn't even use... and a Spy could be something like providing the same explanation you already used that worked.

Lal answered 7/11, 2018 at 11:56 Comment(1)
Not bad ))) and easy to rememberRenatarenate
R
27

let see Test Doubles:

  • Fake: Fakes are objects that have working implementations, but not the same as production one. Such as: in-memory implementation of Data Access Object or Repository.
  • Stub: Stub is an object that holds predefined data and uses it to answer calls during tests. Such as: an object that needs to grab some data from the database to respond to a method call.

  • Mocks: Mocks are objects that register calls they receive. In test assertion, we can verify on Mocks that all expected actions were performed. Such as: a functionality that calls e-mail sending service. for more just check this.

Rennie answered 24/8, 2018 at 6:5 Comment(1)
best answer in my opinionExurb
B
25

I like the explanation put out by Roy Osherove in his talk Understanding Mock Objects:

Every class or object created is a fake. It is a mock if you assert against it. Otherwise it is a stub.

Banka answered 20/2, 2016 at 6:59 Comment(0)
P
22

I think the most important difference between them is their intentions.

Let me try to explain it in WHY stub vs. WHY mock

Suppose I'm writing test code for my mac twitter client's public timeline controller

Here is test sample code

twitter_api.stub(:public_timeline).and_return(public_timeline_array)
client_ui.should_receive(:insert_timeline_above).with(public_timeline_array)
controller.refresh_public_timeline
  • STUB: The network connection to twitter API is very slow, which make my test slow. I know it will return timelines, so I made a stub simulating HTTP twitter API, so that my test will run it very fast, and I can running the test even I'm offline.
  • MOCK: I haven't written any of my UI methods yet, and I'm not sure what methods I need to write for my ui object. I hope to know how my controller will collaborate with my ui object by writing the test code.

By writing mock, you discover the objects collaboration relationship by verifying the expectation are met, while stub only simulate the object's behavior.

I suggest to read this article if you're trying to know more about mocks: http://jmock.org/oopsla2004.pdf

Puerperium answered 8/7, 2012 at 8:37 Comment(1)
I think you have the right idea, but Dillon Kearns explained it a lot more clearly.Repress
P
20

Stub

A stub is an object used to fake a method that has pre-programmed behavior. You may want to use this instead of an existing method in order to avoid unwanted side-effects (e.g. a stub could make a fake fetch call that returns a pre-programmed response without actually making a request to a server).

Mock

A mock is an object used to fake a method that has pre-programmed behavior as well as pre-programmed expectations. If these expectations are not met then the mock will cause the test to fail (e.g. a mock could make a fake fetch call that returns a pre-programmed response without actually making a request to a server which would expect e.g. the first argument to be "http://localhost:3008/" otherwise the test would fail.)

Difference

Unlike mocks, stubs do not have pre-programmed expectations that could fail your test.

Paramedical answered 28/5, 2020 at 17:9 Comment(0)
M
16

I was reading The Art of Unit Testing, and stumbled upon the following definition:

A fake is a generic term that can be used to describe either a stub or a mock object (handwritten or otherwise), because they both look like the real object. Whether a fake is a stub or a mock depends on how it's used in the current test. if it's used to check an interaction (asserted against), it's a mock object. Otherwise, it's a stub.

Mcfarlane answered 31/7, 2019 at 14:13 Comment(0)
S
15
  • Stubs vs. Mocks
    • Stubs
      1. provide specific answers to methods calls
        • ex: myStubbedService.getValues() just return a String needed by the code under test
      2. used by code under test to isolate it
      3. cannot fail test
        • ex: myStubbedService.getValues() just returns the stubbed value
      4. often implement abstract methods
    • Mocks
      1. "superset" of stubs; can assert that certain methods are called
        • ex: verify that myMockedService.getValues() is called only once
      2. used to test behaviour of code under test
      3. can fail test
        • ex: verify that myMockedService.getValues() was called once; verification fails, because myMockedService.getValues() was not called by my tested code
      4. often mocks interfaces
Schroer answered 19/2, 2018 at 23:18 Comment(0)
I
15

Mocks: help to emulate and examine outcoming interactions. These interactions are calls the SUT makes to its dependencies to change their state.

Stubs: help to emulate incoming interactions. These interactions are calls the SUT makes to its dependencies to get input data.

enter image description here

source : Unit Testing Principles, Practices, and Patterns - Manning

Inductee answered 12/7, 2021 at 4:54 Comment(1)
Thank you for posting this image man, it makes more sense now. This answer needs more upvotes!Sedulous
E
14

The generic term he uses is a Test Double (think stunt double). Test Double is a generic term for any case where you replace a production object for testing purposes. There are various kinds of double that Gerard lists:

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
  • Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent(also called Partial Mock).
  • Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.

Source

Eatton answered 29/6, 2017 at 1:45 Comment(0)
G
11

A fake is a generic term that can be used to describe either a stub or a mock object (handwritten or otherwise), because they both look like the real object.

Whether a fake is a stub or a mock depends on how it’s used in the current test. If it’s used to check an interaction (asserted against), it’s a mock object. Otherwise, it’s a stub.

Fakes makes sure test runs smoothly. It means that reader of your future test will understand what will be the behavior of the fake object, without needing to read its source code (without needing to depend on external resource).

What does test run smoothly mean?
Forexample in below code:

 public void Analyze(string filename)
        {
            if(filename.Length<8)
            {
                try
                {
                    errorService.LogError("long file entered named:" + filename);
                }
                catch (Exception e)
                {
                    mailService.SendEMail("[email protected]", "ErrorOnWebService", "someerror");
                }
            }
        }

You want to test mailService.SendEMail() method, to do that you need to simulate an Exception in you test method, so you just need to create a Fake Stub errorService class to simulate that result, then your test code will be able to test mailService.SendEMail() method. As you see you need to simulate a result which is from an another External Dependency ErrorService class.

Gabrielgabriela answered 8/4, 2014 at 18:13 Comment(0)
W
10

Stub

A stub is an object that holds predefined data and uses it to answer calls during tests. It is used when you can’t or don’t want to involve objects that would answer with real data or have undesirable side effects.

An example can be an object that needs to grab some data from the database to respond to a method call. Instead of the real object, we introduced a stub and defined what data should be returned.

enter image description here


example of Stub:

public class GradesService {

   private final Gradebook gradebook;

   public GradesService(Gradebook gradebook) {
       this.gradebook = gradebook;
   }

   Double averageGrades(Student student) {
       return average(gradebook.gradesFor(student));
   }
}

Instead of calling database from Gradebook store to get real students grades, you preconfigure stub with grades that will be returned. You define just enough data to test average calculation algorithm.

public class GradesServiceTest {

   private Student student;
   private Gradebook gradebook;

   @Before
   public void setUp() throws Exception {
       gradebook = mock(Gradebook.class);
       student = new Student();
   }

   @Test
   public void calculates_grades_average_for_student() {
       //stubbing gradebook
       when(gradebook.gradesFor(student)).thenReturn(grades(8, 6, 10)); 

       double averageGrades = new GradesService(gradebook).averageGrades(student);

       assertThat(averageGrades).isEqualTo(8.0);
   }
}


Mock

Mocks are objects that register calls they receive. In test assertion you can verify on Mocks that all expected actions were performed. You use mocks when you don’t want to invoke production code or when there is no easy way to verify, that intended code was executed. There is no return value and no easy way to check system state change. An example can be a functionality that calls e-mail sending service.

You don’t want to send e-mails each time you run a test. Moreover, it is not easy to verify in tests that a right email was send. Only thing you can do is to verify the outputs of the functionality that is exercised in our test. In other worlds, verify that the e-mail sending service was called.

enter image description here


Example of Mock:

public class SecurityCentral {

   private final Window window;
   private final Door door;

   public SecurityCentral(Window window, Door door) {
       this.window = window;
       this.door = door;
   }

   void securityOn() {
       window.close();
       door.close();
   }
}

You don’t want to close real doors to test that security method is working, right? Instead, you place door and window mocks objects in the test code.

public class SecurityCentralTest {

   Window windowMock = mock(Window.class);
   Door doorMock = mock(Door.class);

   @Test
   public void enabling_security_locks_windows_and_doors() {
       SecurityCentral securityCentral = new SecurityCentral(windowMock, doorMock);

       securityCentral.securityOn();

       verify(doorMock).close();
       verify(windowMock).close();
   }
}

Thanks a lot to Michał Lipski for his good article. For further reading:

Test Double – Martin Fowler https://martinfowler.com/bliki/TestDouble.html
Test Double – xUnit Patterns http://xunitpatterns.com/Test%20Double.html
Mocks Aren’t Stubs – Martin Fowler https://martinfowler.com/articles/mocksArentStubs.html
Command Query Separation – Martin Fowler https://martinfowler.com/bliki/CommandQuerySeparation.html

Weave answered 12/4, 2022 at 7:51 Comment(1)
THE BEST EXPLANATION!Aboral
A
9

Right from the paper Mock Roles, not Objects, by the developers of jMock :

Stubs are dummy implementations of production code that return canned results. Mock Objects act as stubs, but also include assertions to instrument the interactions of the target object with its neighbours.

So, the main differences are:

  • expectations set on stubs are usually generic, while expectations set on mocks can be more "clever" (e.g. return this on the first call, this on the second etc.).
  • stubs are mainly used to setup indirect inputs of the SUT, while mocks can be used to test both indirect inputs and indirect outputs of the SUT.

To sum up, while also trying to disperse the confusion from Fowler's article title: mocks are stubs, but they are not only stubs.

Agaric answered 15/1, 2016 at 22:0 Comment(3)
i think you're right, but this is why the Fowler article is confusing, the article title is "Mocks Aren't Stubs"...but they ARE?! ¯_(ツ)_/¯Henrietta
@stonedauwg, indeed, I edited my post to incorporate your pun and a clarification. Hope this helps a bit more.Agaric
@stonedauwg, a mock is not a stub, much like a rectangle is not a square. :)Siddons
R
8

I came across this interesting article by UncleBob The Little Mocker. It explains all the terminology in a very easy to understand manner, so its useful for beginners. Martin Fowlers article is a hard read especially for beginners like me.

Reflection answered 22/1, 2017 at 13:40 Comment(0)
S
8

a lot of valid answers up there but I think worth to mention this form uncle bob: https://8thlight.com/blog/uncle-bob/2014/05/14/TheLittleMocker.html

the best explanation ever with examples!

Strict answered 18/12, 2017 at 15:1 Comment(1)
Link-only answers aren't considered valuable on SO.Sarazen
G
7

A mock is both a technical and a functional object.

The mock is technical. It is indeed created by a mocking library (EasyMock, JMockit and more recently Mockito are known for these) thanks to byte code generation.
The mock implementation is generated in a way where we could instrument it to return a specific value when a method is invoked but also some other things such as verifying that a mock method was invoked with some specific parameters (strict check) or whatever the parameters (no strict check).

Instantiating a mock :

@Mock Foo fooMock

Recording a behavior :

when(fooMock.hello()).thenReturn("hello you!");

Verifying an invocation :

verify(fooMock).hello()

These are clearly not the natural way to instantiate/override the Foo class/behavior. That's why I refer to a technical aspect.

But the mock is also functional because it is an instance of the class we need to isolate from the SUT. And with recorded behaviors on it, we could use it in the SUT in the same way than we would do with a stub.


The stub is just a functional object : that is an instance of the class we need to isolate from the SUT and that's all. That means that both the stub class and all behaviors fixtures needed during our unit tests have to be defined explicitly.
For example to stub hello() would need to subclass the Foo class (or implements its interface it has it) and to override hello() :

public class HelloStub extends Hello{    
  public String hello { 
      return "hello you!"; 
  }
}

If another test scenario requires another value return, we would probably need to define a generic way to set the return :

public class HelloStub extends Hello{    
  public HelloStub(String helloReturn){
       this.helloReturn = helloReturn;
  }
  public String hello { 
      return helloReturn; 
  }
}

Other scenario : if I had a side effect method (no return) and I would check that that method was invoked, I should probably have added a boolean or a counter in the stub class to count how many times the method was invoked.


Conclusion

The stub requires often much overhead/code to write for your unit test. What mock prevents thanks to providing recording/verifying features out of the box.
That's why nowadays, the stub approach is rarely used in practice with the advent of excellent mock libraries.


About the Martin Fowler Article : I don't think to be a "mockist" programmer while I use mocks and I avoid stubs.
But I use mock when it is really required (annoying dependencies) and I favor test slicing and mini-integration tests when I test a class with dependencies which mocking would be an overhead.

Guilbert answered 23/7, 2019 at 6:25 Comment(0)
C
5

Plus useful answers, One of the most powerful point of using Mocks than Subs

If the collaborator [which the main code depend on it] is not under our control (e.g. from a third-party library),
In this case, stub is more difficult to write rather than mock.

Cyclades answered 15/2, 2020 at 0:53 Comment(1)
Makes sense. The expected output could change. However, isn't this the same with Mock. Once you write mocks and expected output changes, you need to change the test code.Linet
P
4

Stub helps us to run test. How? It gives values which helps to run test. These values are itself not real and we created these values just to run the test. For example we create a HashMap to give us values which are similar to values in database table. So instead of directly interacting with database we interact with Hashmap.

Mock is an fake object which runs the test. where we put assert.

Pandowdy answered 30/11, 2013 at 9:44 Comment(1)
"So instead of directly interacting with database we interact with Hashmap." ...because whe had no time yet to code the Database-Module, and we could not run the test-code without using the stub. Otherwise the very same Hasmap would be a mock! right?Absonant
L
4

See below example of mocks vs stubs using C# and Moq framework. Moq doesn't have a special keyword for Stub but you can use Mock object to create stubs too.

namespace UnitTestProject2
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;
    [TestClass]
    public class UnitTest1
    {
        /// <summary>
        /// Test using Mock to Verify that GetNameWithPrefix method calls Repository GetName method "once" when Id is greater than Zero
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
        {
            // Arrange 
            var mockEntityRepository = new Mock<IEntityRepository>();
            mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));

            var entity = new EntityClass(mockEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(12);
            // Assert
            mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Once);
        }
        /// <summary>
        /// Test using Mock to Verify that GetNameWithPrefix method doesn't call Repository GetName method when Id is Zero
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
        {
            // Arrange 
            var mockEntityRepository = new Mock<IEntityRepository>();
            mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
            var entity = new EntityClass(mockEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(0);
            // Assert
            mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Never);
        }
        /// <summary>
        /// Test using Stub to Verify that GetNameWithPrefix method returns Name with a Prefix
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
        {
            // Arrange 
            var stubEntityRepository = new Mock<IEntityRepository>();
            stubEntityRepository.Setup(m => m.GetName(It.IsAny<int>()))
                .Returns("Stub");
            const string EXPECTED_NAME_WITH_PREFIX = "Mr. Stub";
            var entity = new EntityClass(stubEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(12);
            // Assert
            Assert.AreEqual(EXPECTED_NAME_WITH_PREFIX, name);
        }
    }
    public class EntityClass
    {
        private IEntityRepository _entityRepository;
        public EntityClass(IEntityRepository entityRepository)
        {
            this._entityRepository = entityRepository;
        }
        public string Name { get; set; }
        public string GetNameWithPrefix(int id)
        {
            string name = string.Empty;
            if (id > 0)
            {
                name = this._entityRepository.GetName(id);
            }
            return "Mr. " + name;
        }
    }
    public interface IEntityRepository
    {
        string GetName(int id);
    }
    public class EntityRepository:IEntityRepository
    {
        public string GetName(int id)
        {
            // Code to connect to DB and get name based on Id
            return "NameFromDb";
        }
    }
}
Lacker answered 1/1, 2014 at 16:51 Comment(0)
W
4

Both Stubs and Mocks override external dependencies but the difference is

Stubs -> To Test Data

Mocks -> To Test Behavior

A quote from Fowler's Mocks Aren't Stubs article:

  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
  • Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

This obviously tells the difference.


Fake/Dummy -> Test nothing (just override functionality with empty methods, eg replace Logger to avoid any logging noise while testing)

Womanhater answered 26/5, 2019 at 9:53 Comment(0)
P
4

A stub is a test double that returns values to the SUT.

A mock is a test double that a test uses to verify that the SUT correctly invokes a dependency.

Also, a mock is often a stub

Parsifal answered 17/5, 2020 at 12:33 Comment(0)
A
4

There a lots of greats answers, and I liked this one, so I turned it into a table.

Dummy Stub Mock Fake
API O O O O
States X O O O
Values X X O O
Behavior X X X O
Allista answered 19/8, 2022 at 16:34 Comment(1)
A legend would be helpful.Pelargonium
C
3

I have used python examples in my answer to illustrate the differences.

Stub - Stubbing is a software development technique used to implement methods of classes early in the development life-cycle. They are used commonly as placeholders for implementation of a known interface, where the interface is finalized or known but the implementation is not yet known or finalized. You begin with stubs, which simply means that you only write the definition of a function down and leave the actual code for later. The advantage is that you won't forget methods and you can continue to think about your design while seeing it in code. You can also have your stub return a static response so that the response can be used by other parts of your code immediately. Stub objects provide a valid response, but it's static no matter what input you pass in, you'll always get the same response:

class Foo(object):
    def bar1(self):
        pass

    def bar2(self):
        #or ...
        raise NotImplementedError

    def bar3(self):
        #or return dummy data
        return "Dummy Data"

Mock objects are used in mock test cases they validate that certain methods are called on those objects. Mock objects are simulated objects that mimic the behaviour of real objects in controlled ways. You typically creates a mock object to test the behaviour of some other object. Mocks let us simulate resources that are either unavailable or too unwieldy for unit testing.

mymodule.py:

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)

test.py:

from mymodule import rm
import mock
import unittest

class RmTestCase(unittest.TestCase):
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")

if __name__ == '__main__':
    unittest.main()

This is a very basic example that just runs rm and asserts the parameter it was called with. You can use mock with objects not just functions as shown here, and you can also return a value so a mock object can be used to replace a stub for testing.

More on unittest.mock, note in python 2.x mock is not included in unittest but is a downloadable module that can be downloaded via pip (pip install mock).

I have also read "The Art of Unit Testing" by Roy Osherove and I think it would be great if a similar book was written using Python and Python examples. If anyone knows of such a book please do share. Cheers :)

Copyedit answered 13/12, 2014 at 19:35 Comment(0)
L
2

A stub is an empty function which is used to avoid unhandled exceptions during tests:

function foo(){}

A mock is an artificial function which is used to avoid OS, environment or hardware dependencies during tests:

function foo(bar){ window = this; return window.toString(bar); }

In terms of assertions and state:

  • Mocks are asserted before an event or state change
  • Stubs are not asserted, they provide state before an event to avoid executing code from unrelated units
  • Spies are setup like stubs, then asserted after an event or state change
  • Fakes are not asserted, they run after an event with hardcoded dependencies to avoid state

References

Leaguer answered 23/6, 2015 at 15:40 Comment(1)
+1 for adding spies to the glossary. Also, I think you mean "Spies are setup like mocks" not "Spies are setup like stubs"Moores
S
2

Say you have a class named EmployeeService that you want to test and that has one dependency on an interface named EmployeeDao:

public class EmployeeService{
   private EmployeeDao dao;
   public EmployeeService(Dao dao){this.dao = dao;}

   public String getEmployeeName(int id){
     Employee emp = bar.goToDatabaseAndBringTheEmployeeWithId(id);
     return emp != null?emp.getFullName:null;
   }
   //Further state and behavior
}

public interface EmployeeDao{
  Employee goToDatabaseAndBringTheEmployeeWithId(int id);
}

Inside your test class:

public class EmployeeServiceTest{
   EmployeeService service;
   EmployeeDao mockDao = Mockito.mock(EmployeeDao.class);//Line 3

   @Before
   public void setUp(){
     service = new EmployeeService(mockDao);
   }
   //Tests
   //....
}

In the above test class in line 3, we say to the mocking framework (in this case Mockito) "Hey, Mockito, craft me an object that has the EmployeeDao functionality." The framework is going to create an object that has the method goToDatabaseAndBringTheEmployeeWithId but actually with no body. It's your job to instruct that mock what to do. This is a mock.

But you could also create a class that implements the EmployeeDao interface and use it in the test class instead:

public EmployeeDaoStub implements EmployeeDao{
   public Employee goToDatabaseAndBringTheEmployeeWithId(int id){
      //No trip to DB, just returning a dummy Employee object
      return new Employee("John","Woo","123 Lincoln str");
   }
}

Inside your test class this time using stub instead of a mock:

public class EmployeeServiceTest{
   EmployeeService service;
   EmployeeDao daoStub = new EmployeeDaoStub();//Line 3

   @Before
   public void setUp(){
     service = new EmployeeService(daoStub);
   }
   //Tests
   //....
}

So to wrap it all, stubs are the classes that you create(or somebody else does) specifically to imitate some dependency just for the sake of having the desired state. Yes, as all the other people state, it's mostly about a state Whereas mocks are typically created by a mocking framework and you have no idea what its guts look like. But with stubs you know what class you're going to get: It's the one you created.

Oh, btw, if your dependency is a class rather than an interface, you can just extend that class to create your stub.

Sioux answered 12/4, 2019 at 3:16 Comment(0)
R
1

A Stub is an object that implements an interface of a component, but instead of returning what the component would return when called, the stub can be configured to return a value that suits the test. Using stubs a unit test can test if a unit can handle various return values from its collaborator. Using a stub instead of a real collaborator in a unit test could be expressed like this:

unit test --> stub

unit test --> unit --> stub

unit test asserts on results and state of unit

First the unit test creates the stub and configures its return values. Then the unit test creates the unit and sets the stub on it. Now the unit test calls the unit which in turn calls the stub. Finally the unit test makes assertions about the results of the method calls on the unit.

A Mock is like a stub, only it also has methods that make it possible determine what methods where called on the Mock. Using a mock it is thus possible to both test if the unit can handle various return values correctly, and also if the unit uses the collaborator correctly. For instance, you cannot see by the value returned from a dao object whether the data was read from the database using a Statement or a PreparedStatement. Nor can you see if the connection.close() method was called before returning the value. This is possible with mocks. In other words, mocks makes it possible to test a units complete interaction with a collaborator. Not just the collaborator methods that return values used by the unit. Using a mock in a unit test could be expressed like this:

unit test --> mock

unit test --> unit --> mock

unit test asserts on result and state of unit

unit test asserts on the methods called on mock

More Detail >> Here

Ribosome answered 23/1, 2015 at 8:0 Comment(0)
G
1

A stub is a fake object built for test purposes. A mock is a stub that records whether expected calls effectively occurred.

Gabriello answered 21/12, 2016 at 18:56 Comment(0)
C
1

Mock - A mock intercepts a call to a method or function (or a group of methods and functions like in the case of a mocked class). It is not an alternative to that method or function. In that interception, the mock can do whatever it wants, such as record the input and output, decide to short circuit the call, change the returned value, etc.

Stub - A stub is a valid full working implementation of a method or function (or group of methods and functions like in the case of a stubbed class) that has an identical interface/signature to the method, function or group of methods and functions it is stubbing for. The stubbed implementation will generally only do things that are acceptable within the context of a unit test, that means it won't do IO for example, while mimicking the behavior of the thing it is stubbing.

Calm answered 29/6, 2017 at 0:5 Comment(0)
S
1

A test subject performs actions in response to certain prompts (function calls) or other stimuli. Here are concrete examples of test situations.

Scenario -- EMT student exam

A student has studied to be an Emergency Medical Technician. Go watch Ian Gallagher in Shameless Season 6, Episode 10 if you are unfamiliar with this test situation.

It is too expensive to find patients with various illnesses for test purposes. Instead we use actors. We ask the test subject (Ian) "you arrive on the scene and the patient is immobilized and unconscious what do you do first?" Ian responds "I check if the scene is safe". And the test instructor says "the scene is safe".

The instructor (and actor) are able to inject arbitrary answers to the test subject's queries.

Here, the instructor (and actor) are a mock. Medical training uses this terminology (e.g. mock code simulation) the same as computer scientists.

Scenario -- register for a website

You are testing Yahoo, a new email service you heard about. In order to sign up, you must provide your birthday and answers to other intrusive questions.

The website requires that you are 21 years or older. So you enter in the value January 1, 1970. It meets the requirements and it saves you from the laborious process of implementing a remember-my-birthday-and-type-it-in workflow.

This date is a stub. This word usage is specific to computer science.

Sedate answered 28/10, 2018 at 18:55 Comment(0)
R
0

following is my understanding...

  • if you create test objects locally and feed your local service with that, you are using mock object. this will give a test for the method you implemented in your local service. it is used to verify behaviors

  • when you get the test data from the real service provider, though from a test version of interface and get a test version of the object, you are working with stubs the stub can have logic to accept certain input and give corresponding output to help you perform state verification...

Rayleigh answered 11/8, 2010 at 14:37 Comment(0)
I
0

Stubs are used on methods with an expected return value which you setup in your test. Mocks are used on void methods which are verified in the Assert that they are called.

Interdictory answered 17/3, 2013 at 15:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.