Hi devs, I've been writing tests in druid for a little bit now and wanted to hear your thoughts on using EasyMock as the mocking framework.
I've found it pretty tedious to write tests using easy mock because it's very verbose, and requires me to do a lot of set up for the mock objects. Because of this setup work, the mocks tend to be very tightly coupled with the implementation which makes it harder to refactor in the future. The extra stubbing work also discourages me from adding more tests. *IMO, this makes it harder for us to write well tested code.* TL;DR at the bottom with questions for those on this list I've used Mockito in the past, and find it to be more fluent when writing tests. See this example for a side by side comparison. *Using Mockito* - create a mock object that returns mock objects for every function call. @Mock(answer = Answers.RETURNS_MOCKS) private IndexTask.IndexIngestionSpec ingestionSpec; *Using EasyMock* @Mock private IndexTask.IndexIngestionSpec ingestionSpec; @Mock private DataSchema dataSchema; @Mock private IndexTask.IndexIOConfig indexIOConfig; @Mock private IndexTask.IndexIOConfig indexTuningConfig; @Before public void setUp() throws IOException { EasyMock.expect(ingestionSpec.getDataSchema())andStubReturn(dataSchema); EasyMock.expect(ingestionSpec.getIndexIOConfig())andStubReturn(indexIOConfig); EasyMock.expect(ingestionSpec.getIndexTuningConfig())andStubReturn(indexTuningConfig); EasyMock.replay(ingestionSpec); ... Now if the interface of ingestionSpec changes to add a new method, we need to stub that in the tests as well. If getDataSchema() is called an extra time the mock throws an exception because it's not expected that the function will be called twice IMO this makes them brittle because they are tightly coupled to the code. With Mockito, you only need to mock objects that you want to interact with in the tests. @Mock(answer = Answers.RETURNS_MOCKS) private IndexTask.IndexIngestionSpec ingestionSpec; @Mock(answer = Answers.RETURNS_MOCKS) private DataSchema dataSchema; @Before public void setUp() throws IOException { Mockito.when(ingestionSpec.getDataSchema()).thenReturn(dataSchema); Mockito.when(dataSchema.getDimensionsSpec()).thenReturn(dimensionsSpec); ... Another feature of Mockito I like is that it allows you to spy real objects. So if you have a class that creates a File, you can spy the function and give it a fake File to operate on instead of having your tests have to create real files. For example, below is some test code that doesn't get a real InputSourceReader which means the test doesn't need to add any set up code to get the reader. It simply says, if you need to use an inputSourceReader - use this one. target = Mockito.spy(new IndexedTableSupplier(INDEX_KEYS, ingestionSpec, () -> tmpDir)); Mockito.doReturn(inputSourceReader).when(target).getInputSourceReader(dataSchema, tmpDir); Here's a list of similarities/ differences between the frameworks - https://github.com/mockito/mockito/wiki/Mockito-vs-EasyMock Here's a stackoverflow post asking about maintainability in large projects - https://stackoverflow.com/questions/2864796/easymock-vs-mockito-design-vs-maintainability *TL;DR: *Am I using EasyMock incorrectly? Do these features exist and I just don't know how to use them? What would it take for us to try another framework like Mockito?