Reputation: 2090
I'm writing some simple unit tests for a method which acts like a database query: it returns a list of results that can be customised using a limit (max of n results) and a page (the p'th set of n results). I'd like to test a few cases, such as:
I need to mock the results (effectively names) that are returned, so I'm just generating them with a counter to make a list of "Name #1", "Name #2", etc. for as many as I need. Each test looks (roughly) like:
public void testGetMockCandidatesLimited() throws Exception {
int numResults = 4;
setupMock(numResults);
results = queryFunction(...);
// Check that the expected number of results was returned
assertEquals(numResults, results.size());
// Check that the results are correct and in order
for (int i = 0; i < numResults; i++) {
assertEquals(result.get(i).getName(), "Name #" + (i + 1));
}
}
My question is: is it okay to 'generate' the expected answers in this way? This is a trivial example, but the next step was to write a test to write a test to get the second page of two results each, and I had:
final int TEST_LIMIT = 2, TEST_PAGE = 1;
// Check that the expected number of results was returned
assertEquals(numResults, results.size());
// Check that the results are correct and in order
for (int i = TEST_LIMIT * TEST_PAGE; i < TEST_LIMIT * TEST_PAGE + TEST_LIMIT; i++) {
assertEquals(result.get(i).getName(), "Name #" + (i + 1));
}
Now it just so happens that this test is 'correct' in the sense that i will take on the values that I expect it to and ensure that the results are "Name #3" and "Name #4". However it also happens that my queryFunction calculates which results to return in the same way (limit * page + limit
kind of thing).
This is concerning because if the test generates the expected answers in the same way that the unit under test does, it won't detect if there's a bug in that approach. However naming the input values with constants makes the tests much more readable than just have magic integers between 1 and 4 plugged in everywhere.
What is the best way to deal with this situation, for both readability and maintainability (e.g. changing values in the future, should you need to)?
Upvotes: 1
Views: 1075
Reputation: 2090
In asking this question I think I've convinced myself that the solution is to define the expected values as constants up front as well, such as:
final int LIMIT = 2, PAGE = 1, MIN_RESULT = 3, MAX_RESULT = 4;
... and then use those values in the assertions. This retains all the readability of named key values, and discourages the temptation to generate the expected outputs. In this case I would still be using a loop to generate each expected name between Name #MIN
and Name #MAX
, but the bounds themselves would be explicitly static.
Is this as good as it gets, or are there better ways to deal with this repetitiveness?
Upvotes: 1