Expected Before Actual Value

 class​ CruiseControlTest {
 
  @Test
 void​ setPlanetarySpeedIs7667() {
  CruiseControl cruiseControl = ​new​ CruiseControl();
 
  cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
 
» Assertions.assertEquals(cruiseControl.getTargetSpeedKmh(), 7667);
  }
 }

The test above looks correct, doesn’t it? You can see its structuring into different parts, it uses assertEquals() to compare the results, and it has a meaningful name. You need to look closely to find a problem in the code.

It gets more obvious when you run the test and the assertion fails. If that happens, you’ll get a message like this one:

expected: <1337> but was <7667>

The message tells you that the two values in the assertEquals() method are different. That’s why the test fails as it should. So far so good, but the semantics of the message are wrong. In the test, we expect the number 7667 as the correct result and 1337 is the incorrect result that the cruiseControl returns. But the message tells you that it’s the other way around.

The error comes from a mix-up in the arguments to assertEquals()—they’re in the wrong order. Unfortunately, Java or JUnit can’t provide us with type checking support here. After all, the types of expected and actual values need to be the same. The ordering is a purely semantical problem, and it’s easy to get it wrong by accident.

In this simple test, we can quickly determine how the message should be. No real problem here. But think about a more complex invocation of assertEquals() that compares large objects that don’t give you such an easy view as the int values here. You’ll have a hard time understanding the error, and you might go down the wrong road for debugging the cause of it, simply because you’ll assume that the message is correct. At least that’s the baseline assumption when you read the message of a failing test, and you’d better make sure that it holds.

It’s important to take care of the order of arguments for assertEquals() here:

 class​ CruiseControlTest {
 
  @Test
 void​ setPlanetarySpeedIs7667() {
  CruiseControl cruiseControl = ​new​ CruiseControl();
 
  cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
 
» Assertions.assertEquals(7667, cruiseControl.getTargetSpeedKmh());
  }
 }

As you’ve probably guessed, the solution is very simple in this case. We just need to switch the two arguments of the assertEquals() method.

The error message for our assertion then turns into:

expected: <7667> but was <1337>

That’s much better! Now, the message provides the right information and doesn’t mislead you any longer. Our rule of thumb is: think first about what you expect.

The hard part isn’t fixing the bug; it’s avoiding it to begin with. We observed this error a lot in code from Java beginners, and we’ve also seen it in professional code. Yes, it seems like a minor issue. But clear and descriptive assertion messages are tremendously helpful in times of need (failing tests); you’re going to be very thankful for meaningful error messages that lead you toward a fix and not in the opposite direction. We’ve been very thankful for those messages many times over.

This chapter is also a reminder to expect the unexpected. When something breaks in the code, make sure that you have all the information at hand to get a fast understanding of what the correct behavior should be and what part of the code causes the trouble. Having the right order of arguments is one aspect. Others are using fitting assertions (as in the preceding comparison) and configuring them properly, as you’ll learn next: Use Reasonable Tolerance Values.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.233.153