Mocking Flashcards
(9 cards)
What is mocking?
- Mock objects are dummy implementations of our dependencies that allow us to define the output of their method calls - used in testing, to write deterministic tests : we determine what behavior to mock, so that our test can respond to this behavior.
- Mock objects are dummy objects that simulate the behavior of real objects in a simulated, controlled way. They are used to test the behavior of some other product, i.e. mocks are simulated dependencies, used to test the behavior of the dependent object when responding to the simulation.
example of a mocked object
Say we have an OrderDao class. It has a method getOrder that retrieves an order from the database. We can create a mocked object of this class and force the getOrder method to return an Order without ever hitting the database.
Why do we mock?
- Mocking keeps unit testing independent from dependencies.
- Mocking allows our unit tests to be deterministic (know exactly the unit we are testing and only that unit)
- Mocking allows us to test hard to reproduce use cases
- Mocking is fast (no waits to connect to database for example) and free of false alarms relative to the unit being tested
- Mocking is free: some APIs cost money per request (google maps, machine learning data)
- Test data would pollute a real database or storage container. Example: if we test “registerUser” method, the test user would persist in the registrar, polluting the registrar and preventing the test from running again (since the test user already exists in the registrar, we cannot register the user again).
Deterministic tests always…
…produce the same result from a given starting condition or initial state (since the “instantiated” (mocked) dependencies are static data, and the functionality of the class is also “static” (until a new requirement changes functionality down the line)
Example of a deterministic test
“Get the current temperature in Seattle for a user who prefers the fahrenheit scale”
Alexa skill class contains a getTemperature method:
dependencies are
1) user preference for scale (F or C)
2) city of interest, e.g. Seatle
3) WeatherService class or API getCurrentTemperature
These dependencies need to be mocked, in particular if we called the real weather serive, the temperature will change each time the method is called, so we could not assertEquals.
We can force the mocked weather service to always return 75F when asked for the temp in Seattle by a user who prefers fahrenheit (note that the weather service has its own unit testing to see if it is returning the correct temperature, here we are not testing the weather service, but testing that the getTemperature behaves as expected when asked to retrieve temperature with parameters and receiving a valid reply from the weather service).
setup steps for test class to use Mockito
Mockito is used in conjunction with JUnit
1. @Mock the dependencies and insert the mocks into the test code
@Mock
private DependencyClass1 dependencyClass1;
@Mock
private DependencyClass2 dependencyClass2;
- annotate the class being tested with @InjectMocks
@InjectMocks
private ClassUnderUnitTest myUnitTestClass; - in test setup(), we don’t create a new ClassUnderUnitTest: instead we call the Mockito method initMocks() passing in this (our test class instance)
@BeforeEach
public void setup() {
initMocks(this);
}
–>then we set up the unit test methods with deterministic test data to have dependencies return determined/expected data (see other card where we define when().thenReturn and other Mockito methods)
Mockito mock throws an exception - how to write the //Then portion of the test?
doThrow().when().write()
Unless otherwise specified in the unit tests, mock objects will return …
…default values when their methods are called. For Java objects, the default value is null; for primitave boolean, it’s false; for primitive int, it’s 0; (see oracle documentation)
For Mockito mock, how to write the //Then portion of a test saying when the mocked object RenterDao’s method getRegisteredRenter() is called with the driver license driverABCLicenseId, the method should return the Driver driverABC?
when(renterDao.getRegisteredRenter(driverABCLicenseId)).thenReturn(driverABC);
Note: only when getRegisteredRenter is called with driverABCLicenseId will above get triggered! If I call getRegisteredRenter with driverXYZLicenseId, the default driver (null) will be returned.
previously setup may have needed to set up the registered driver in the //Given section:
renterRegistrar.registerRenter(driver);
with mocking, we don’t have to actually register a driver, which would pollute the database.