# Mock Testing

## Summary


Mock testing is an approach to unit testing that lets you make assertions about how the code under test is interacting with other system modules. In mock testing, the dependencies are replaced with objects that simulate the behaviour of the real ones. The purpose of mocking is to isolate and focus on the code being tested and not on the behaviour or state of external dependencies. 

Let's say, a notification service triggers an email service. We don't want to send emails each time we run a notification test. However, we want to verify that the email-sending service is called. Such a service can be replaced with a mock object.

## Discussion

### Where is mock testing useful?

Mocking is generally useful during unit testing so that external dependencies are no longer a constraint to the unit under test. Often those dependencies may themselves be under development. Without mocking, if a test case fails, it will be hard to know if the failure is due to our code unit or due to dependencies. Mocking therefore speeds up development and testing by isolating failures. 

Other reasons to mock dependencies is to avoid slow network calls or call third-party APIs. Mocking also enables product demos and evaluations. All units of a project can progress in parallel without waiting for everyone to be ready. Thus, testing can start early. 

Code that have side effects should be called only in production. Examples include charging a credit card or sending a notification. Mocking is useful to validate such calls without the side effects. 

Mocking avoids duplicating test code across similar tests. The task of verifying method or API calls from our module can be delegated to the mock. 


### Could you give some examples of mock testing?

Let's say, an Order class fulfils orders by calling a Warehouse class. The latter knows the current inventory. If we are unit testing Order class, we mock the Warehouse. We don't care about testing Warehouse right now. But since it's a dependency for Order, we mock it. Our mock object can be called WarehouseMock. 

A **mock object** provides a pseudo implementation of the same interface as the real object. Those calling it are unaware that it's a mock. Thus, to the Order class, WarehouseMock looks the same as Warehouse. This is just what we need to unit test Order class.

Another example is about an application calling an external API to get information about movies. Instead of making real calls, this can be mocked so that when API calls are made, the mock object will simply read and respond with test data from a local file system. 


### Does mocking require developers to modify their codebase?

If your code uses static objects or singletons, then it's difficult to do mocking. In such cases, it's better to refactor code. Otherwise, in general, mocking doesn't require you to modify the codebase. In fact, **dependency injection** is the usual way in which objects should be created. Dependencies become visible in the constructors and other methods. These dependencies can therefore be easily replaced during testing with mock objects.  This can be configured either in code or via a configuration file. 


### How is mock testing different from traditional unit testing?

In traditional unit testing, unit tests do assertions about states expected of either the system under test or its dependencies. With mock testing, no assertions are required from the unit tests themselves. Assertions are done by the mock objects. These objects are initialized in advance about what method calls are expected and how they should respond. 

While unit tests are more about **state-based** verification, mock testing is more about **behaviour-based** verification. For example, let's assume that SecurityCentral is being tested. It depends on Door. When SecurityCentral activates full security, unit testing will verify the final state of Door, that it's closed. Mocking would instead verify that the correct method was invoked with expected arguments, such as `Door.close()`. Mocks register the calls they receive so these can be asserted. 


### What are the common types of mock testing?

In **proxy-based mocking**, a proxy object is used instead of the original object. The proxy may handle all calls to the original object or selectively forward some calls. Mock frameworks such as EasyMock, JMock, Mockito offer this type of mocking. However, there may be limitations in terms of proxying `static/private/final` methods or a `final` class. 

In **classloader-remapping-based mocking**, a class loader remaps the reference. Thus, it loads the mock object rather than the original one. Mock frameworks such as JMockit and PowerMock support this. This overcomes the limits of proxy-based mocking. 

In Swift language, one developers blogged that he uses two ways to do mocking: **instance injection** and **configuration injection**. The former is simpler but it can't handle static objects. 


### What are some best practices for mock testing?

Here are some best practices for mocking:

    + **Only mock types that you own:** External types have dependencies on their own. They might even change their behaviour in a future version. Instead, create an adapter and mock that adapter.
    + **Don't mock values:** Values should not be mocked. Mocking aims to make the relationships and interactions between objects visible. Getting a value is not an interaction.
    + **Avoid mocking concrete classes:** Relationships are easier to see via interfaces rather than concrete classes. We might end up mocking some methods but forget others. Mock roles, not objects.
    + **Don't mock everything:** This is an anti-pattern. If everything is mocked, we may end up testing something quite different from production system.
    + **Use integration tests**: When testing multiple modules or if you're interested in data coming from an external database, you should do integration testing rather than mocking.
    + **Negative tests**: Use mocks to simulate errors and test error handling. Use mocks to verify that some methods/APIs are *not* called.

### What are some mocking frameworks?

While it's possible to manually write mock objects, mocking frameworks simplify the task. Mockito is an open source testing framework for Java. Mockito is claimed to be the one of the popular ones. 

JustMock and MOQ package are useful for .NET developers. . There's also JustMock Lite when dealing with loosely coupled code. Wiremock is suitable for mocking HTTP-based APIs.

For C++ developers, there's TypeMock and Google Mock. The latter is part of GoogleTest. TypeMock uses a templating approach to create mocks whereas Google Mock uses inheritance. 

Other frameworks include EasyMock, JMock, JMockit, and PowerMock. Ease of use, maintainability and learning curve are some things to consider when choosing a framework. 


### What are some limitations of mock testing?

Writing good mocks requires good understanding of dependencies. Otherwise, mocks may not accurately represent real-world behaviour. Mocking can lead to tight coupling between mocks and code under test. 

Overuse of mock objects as part of a suite of unit tests can result in a dramatic increase in the amount of maintenance that needs to be performed on the tests themselves. 

## Milestones

1999

Extreme Programming emphasizes unit testing and Test-Driven Development (TDD). Some adopters of Extreme Programming, based out of London, begin to think about how testing influences coding. They have been using "getters" to facilitate testing but they explore new ideas. They start avoiding "getters" and adopt **composition**, where test objects are passed via constructors. This is years before the term **Dependency Injection** is used for this design approach. 

2000

Initial ideas of mock testing are presented at the XP2000 conference. At this time, the approach is called **Endo-Testing**. This name comes from the fact that mock objects are passed into domain code and tested from within. They claim that this simplifies testing architecture. It avoids polluting domain code since assertions are not in production code but in unit tests. 

2001

EasyMock is released. It's the first library to provide dynamic mock objects. 

Jun  
2004

Version 1.0.0 of **jMock** is released. This provides an expressive API over **DynaMock** Java library. DynaMock itself comes from an earlier work by Nat Pryce who introduced mocking to Ruby. He emphasized assertions on messages passed between objects rather than just parameter values. 

Jul  
2008

Framework **Mockito** v1.5 for Java is released. By now, mock testing is more than just identifying where a test has failed. It's more about interactions among objects. Mockito simplifies mocking by taking a different approach compared to jMock or EasyMock. We don't have to set up expectations in mock objects in advance. We can simply create them and query them later after execution. 

Apr  
2007

Nat Pryce and Steve Freeman rework jMock to produce **jMock2**.  

Dec  
2008

Google releases **Google Mock**, a mocking framework for C++. Version 1.7.0 is released in 2013. In 2015, this is absorbed into the GoogleTest project.