The difference between mocks and stubs, explained with JS
Tags: javascript, testing, tdd, beginners
Published: 2019-08-22 20:25:17

---
title: The difference between mocks and stubs, explained with JS
published: true
description: A simpler explanation for mocks vs stubs
tags: javascript, testing, TDD, beginner
---

Stubs and Mocks are two foundational concepts in testing that are often misunderstood. So much so, that we have the famous [Martin Fowler article](https://martinfowler.com/articles/mocksArentStubs.html) on the subject, alongside numerous stackoverflow questions on the matter.
Martins article is a long read for the modern impatient reader, get somewhat sidetracked and doesn't have example in the current hype language, JS.
I'll try to be more concise in my explanations here.

I'll start with the headline definition:
**Stubs and mocks are both dummy objects for testing, while stubs only implement a pre-programmed response, mocks also pre-program specific expectations.**

To put it into a workflow:
### Stubs
- **Setup** - define the stub itself, what object in the program you are stubbing and how
- **Exercise** - run the functionality you want to test
- **Verify** - check the stub for values that ran through it, that they fit expectations
- **Teardown** - if needed, clean up. e.g Time stubs are usually global, you need to yield control back

### Mocks
- **Setup object** - define the mock, what object you are mocking and how (similar to stubs)
- **Setup expectations** - define what you expect will happen to this mock internally
- **Exercise** - run the functionality you want to test
- **Verify mock** - verify that the mock expectations are met. In some JS libraries this happens automatically without additional call, the mock expectations are verifying themselves and will throw if needed. (Used mostly when async testing).
- **Verify** - verify any additional expectations for results on the mock
- **Teardown** - if needed, clean up.

### Mocks & Stubs in the JS community
Before we get into code, since my examples will be in JS, there is an important note to be said here.

One of the most successful testing libraries in the JS community is [jest](https://jestjs.io). But I will not use it for my examples, for the simple reason that jest is opinionated and does not implement mocks.
What they call a `mock` in the library, is actually a stub by definition. You cannot make expectations on the mock itself, rather just look at its behavior and call and make expectations on that.

I will demonstrate the concept using `sinon.js` that does implement the concepts of both mocks and stubs.

### Stubs example
For our example, we will unit test an imaginary function for purchasing items in an eCommerce site. We will try to pay and get the payment status, and if we are successful we will send a mail.

```javascript
const purchaseItemsFromCart(cartItems, user) => {
  let payStatus = user.paymentMethod(cartItems)
  if (payStatus === "success") {
    user.sendSuccessMail()
  } else {
    user.redirect("payment_error_page")
  }
}

}
"when purchase payed successfully user should receive a mail" : function() {
  // Setup
  let paymentStub = sinon.stub().returns("success")
  let mailStub = sinon.stub()
  let user = {
    paymentMethod: paymentStub,
    sendSuccessMail: mailStub
  }
  
  // Exercise
  purchaseItemsFromCart([], user)

  // Verify
  assert(mailStub.called)
}

```

### Mocks example
Now lets do the same, using mocks.
```javascript
"when purchase payed successfully user should receive a mail" : function() {
  // Setup objects
  let userMock = sinon.mock({
    paymentMethod: () => {},
    sendSuccessMail: () => {}
  })

  // Setup expectations
  userMock.expect(paymentMethod).returns("success")
  userMock.expect(sendSuccessMail).once()
  
  // Exercise
  purchaseItemsFromCart([], user)

  // Verify mocks
  userMock.verify()
}
```

## Great. When should I use each?
Now this is the interesting question here.
And there is much debate - there is a reason the guys behind `jest` decided not to implement classic mock functionality.

Mocks can do whatever stubs can do, plus setting expectations directly on the objects they are faking.
This creates readability problems for large tests as well as tendency to start expecting and testing fake objects within the test that are not the sole purpose of the test, making it a white-box test that is too aware of internals.

That is even mentioned as a guideline in sinon documentation for when to use a mock:
```
Mocks should only be used for the method under test.
In every unit test, there should be one unit under test.
```

So to not overuse this functionality and create a confusing, and maybe mispurposed test, you should limit your mocks usage in tests to one object.

Or, you know, you could just use jest that took this decision away from you by not implementing these kind of mocks in the first place.