Your task is to simplify the testing of this function logic:
function calculate () {
int a = serviceA.getA()
int b = serviceB.getB()
return a + b * log(b)/a
}
How easy is it to test this function? Not complicated, but not trivial either. We can use mocking:
function testCalculate () {
//pseudo-coding
serviceA = mock(serviceA).when(getA()).return(3)
serviceB = mock(serviceB).when(getB()).return(6)
calculator = new Calculator(serviceA, serviceB)
assert calculator.calculate() == 10.5
}
As you can see, a certain amount of test code is needed. This example is simple, but imagine that you have more complex logic and classes with many dependencies. A test in such a case requires dozens of lines of code and analysis of what and how to mock!
You couldn’t test it as black-box, because you need to know how to mock up, you need to know the logic.
Could testing be simpler? Yes. What we want to test is the calculation logic, which is the most important, so we can extract it to a separate function and pass all the required parameters:
function calculate () {
calculate (serviceA.getA() , serviceB.getB())
}
function calculate (int a, int b) {
return a + b * log(b)/a
}
Now the test is trivial:
function testCalculate () {
assert 10.5 == new Calculator().calculate(3,6)
}
You can say that in this case, we are not testing integration with services. This is true, but is it really important? I don’t think so. Integrations are best tested with acceptance tests that use real data. Our main goal is to test the risky parts, in our case, it is the calculation formula.
Advantages:
- simplicity of testing – even if the function requires complex parameters, you can still use the simplest way to test, most often without mocking
- clarity – you can see what the parameters are, so you can even guess what the function is doing, and it will be easier for your brain to read the code, for example:
calculate (int productPrice, int numberOfProducts, int discount)
Even if the function name is incorrect – the name is too generic, we can guess what the function does!