...
Code Block | ||||
---|---|---|---|---|
| ||||
/** * Checks the construction of a FlowId object. */ @Test public void testConstruction() { final long flowIdValue = 7777L; final FlowId flowId = FlowId.valueOf(flowIdValue); assertThat(flowId, is(notNullValue())); assertThat(flowId.value(), is(flowIdValue)); } |
Mocking
Mocking is a useful strategy for limiting the interaction between your code under test and other modules that are required to satisfy dependencies. There are several strategies that may be used for mocking, two that are used inside of ONOS are described here.
EasyMock Mocking Framework
EasyMock allows a test to create a mocked object directly from an interface, without having to define a class and mock every method defined by the API. The test writer can define only the methods that are required to execute the test. In this example, a mock is created for the HostService API which is passed in to the HostToHostIntentCompiler class.
Code Block | ||||
---|---|---|---|---|
| ||||
import static org.easymock.EasyMock.*;
private HostService mockHostService;
private static final String HOST_ONE_MAC = "00:00:00:00:00:01";
private static final String HOST_TWO_MAC = "00:00:00:00:00:02";
private static final String HOST_ONE_VLAN = "-1";
private static final String HOST_TWO_VLAN = "-1";
private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN;
private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN;
private HostId hostOneId = HostId.hostId(HOST_ONE);
private HostId hostTwoId = HostId.hostId(HOST_TWO);
@Test
public void testHostToHostIntentCompiler() throws Exception {
mockHostService = createMock(HostService.class);
expect(mockHostService.getHost(eq(hostOneId))).andReturn(hostOne).anyTimes();
expect(mockHostService.getHost(eq(hostTwoId))).andReturn(hostTwo).anyTimes();
replay(mockHostService);
final HostToHostIntentCompiler compiler = new HostToHostIntentCompiler();
compiler.hostService = mockHostService;
final Intent intent = new HostToHostIntent(APPID, hid(oneIdString), hid(twoIdString),
selector, treatment);
final List<Intent> result = compiler.compile(intent, null, null);
assertThat(result, is(Matchers.notNullValue()));
assertThat(result, hasSize(2));
}
|
Custom Mocks
Sometimes a test writer will want to implement their own complete mocked implementation of an API rather than use the mocking framework. This can be accomplished by creating a class that implements the API interface, and then implementing the methods to do whatever the test requires.
Code Block | ||||
---|---|---|---|---|
| ||||
private static class TestIntentCompilerError implements IntentCompiler<Intent> {
@Override
public List<Intent> compile(Intent intent, List<Intent> installable,
Set<LinkResourceAllocations> resources) {
throw new IntentCompilationException("Compilation always fails");
}
}
/**
* Tests for proper behavior of installation of an intent that triggers
* a compilation error.
*/
@Test
public void errorIntentCompile() {
final TestIntentCompilerError errorCompiler = new TestIntentCompilerError();
final IntentManager intentManager = new IntentManager();
final IntentExtensionService extensionService = intentManager;
final IntentService intentService = intentManager;
extensionService.registerCompiler(MyIntent.class, errorCompiler);
MyIntent intent = new MyIntent();
// Invoke the error compiler
intentService.submit(myIntent);
} |
Hamcrest
Hamcrest is a powerful framework for defining matchers for data values in tests. ONOS uses version 1.3 of Hamcrest. Contributors are encouraged to learn about and use the Hamcrest framework, particularly when working with arrays and collections. Hamcrest also gives you the ability to write your own matchers, which will make your tests easier to read and easier to extend by other developers.
...