The Most Lightweight New Mock Tool of Alibaba for Unit Testing Is Open-Source!

Introduction

The Eight Steps of Mock Test

// Step 1: initialize Mockito
@RunWith(MockitoJUnitRunner.class)
public class RecordServiceTest
{
// Step 2: define a mock object
@Mock
DatabaseDAO databaseMock;
// Step 3: define test cases
@Test
public void saveTest()
{
// Step 4: define alternative methods
when(databaseMock.write()).thenReturn(4);
// Step 5: inject mock object
RecordService recordService =
new RecordService(databaseMock);
// Step 6: execute test content
boolean saved = recordService.save("demo");
// Step 7: verify test results
assertEquals(true, saved);
// Step 8: verify whether the mock method is executed
verify(databaseMock, times(1)).write();
}
}
// Step 1: initialize JMockit
@RunWith(JMockit.class)
public class PerformerTest {

// Step 2: define a mock object
@Mocked
private Collaborator collaborator;

// Step 3: define the object to be tested
// Implicitly inject the logic of the mock object
@Tested
private Performer performer;

// Step 4: define test cases
@Test
public void testThePerformMethod() {
// Step 5: define alternative methods
new Expectations() {{
collaborator.work("bar"); result = 10;
}};
// Step 6: execute test content
boolean res = performer.perform("test");
// Step 7: verify test results
assertEquals(true, res);
// Step 8: verify whether the mock method is executed
new Verifications() {{
collaborator.receive(true);
}};
}
}

Extremely Simple TestableMock

public class RecordServiceTest 
{
// Define mock target and alternative methods inside an inner class
public static class Mock {
// The mock method has one more parameter than the original method and is passed into the caller.
// So it replaces the int write() method call of the DatabaseDAO class
@MockMethod
int write(DatabaseDAO origin) { return 4; }
}
// Define test cases
@Test
public void saveTest()
{
// Execute test content
RecordService rs = new RecordService();
boolean saved = rs.save("demo");
// Verify test results
assertEquals(true, saved);
// Verify whether the mock method is executed
TestableTool.verify("write").times(1);
}
}
  • Assumption 1: In the same tested class, if methods in one test case are replaced by Mock, these methods will be replaced with other cases. These methods often access external dependencies that are not easily tested.
  • Assumption 2: All calls that need to be replaced by mock are codes of the tested class. This assumption is in line with the idea of unit testing. Unit testing should only focus on the internal behavior of the current unit, while the logic outside the unit should be replaced by Mock.
@MockMethod
int write(DatabaseDAO origin) {
switch(TestableTool.SOURCE_METHOD) {
case "save": return 10;
default: return origin.write();
}
}

The Principle of TestableMock

  • Dynamic Proxy: Mockito, EasyMock, and MockRunner
  • Customized Class Loader: PowerMock
  • Runtime Bytecode Modification: JMockit and TestableMock

Be More Than a mock Tool

Summary

Original Source:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store