Unit Testing – Most Concise Way to Test Boolean Condition with Many AND Clauses

conditionsunit testing

I have a function which returns the availability of a module, where the module is only available if multiple conditions are all met. The code looks like this:

bool isShipAvailable() {
  bool isAvailable;

  isAvailable = this->areSystemsCalibrated;
  isAvailable = isAvailable && this->areEnginesFunctional;
  isAvailable = isAvailable && this->isWarpDriveOnline;
  isAvailable = isAvailable && this->isFluxCapacitorOnline;
  isAvailable = isAvailable && this->areStabilizersOnline;

  return isAvailable;
}

I'm trying to test this code without creating something large or difficult to maintain. I know I could write tests for all permutations, but would it be acceptable to test the case where all conditions are true and then test each scenario where only one condition is false? Would that be making too many assumptions about the implementation in the tests?

Edit: I'm not asking how to refactor the boolean logic to be concise, but rather what the shortest way to test every permutation of that logic would be. The details of the implementation itself are not terribly important.

Best Answer

Unit testing is about behaviour of the code under test from the point of view of its clients. Therefore, as your test class is one of its clients, you should define what are your expectations.

There's a few expectations I see from your implementation :

  1. Given that the systems are calibrated, the engines are functional, the warp drive is online, the flux capacitor is online and the stabilizers are online, then the ship is available.1
  2. Given that the systems are not calibrated, then the ship is unavailable.
  3. Given that the engines are non functional, then the ship is unavailable.
  4. And so on.

Therefore, I would expect 6 tests, as there are 6 distinct behaviours I care about as a client.

Would that be making too many assumptions about the implementation in the tests?

Quite funny, because I actually believe the reverse is true: you are making too many assumptions about your implementation when you test every combination. Remember that you always test from the point of view of your clients. If you test every single combination, then you're saying that your clients care about all those combinations. My understanding of your code is that it doesn't matter which combination of systems are offline or non functional. As long as one subsystem is offline, then the ship is unavailable, period. Therefore, I would test it as such.

1. Phew, that might require quite of a setup to test this assertion. If that's your feeling as well, then maybe your tests are speaking to you: your code under test is doing quite a lot.

Related Topic