Search code examples
unit-testingoopblack-box-testing

Unit tests strategy : redundancy using Black-box


I'am having an issue designing black-box unit tests without redundancy.

Here is an example :

class A {
   Float function operationA(int: aNumber){
        if(aNumber > 0){
            return aNumber * 10 + 5.2;
        }
        else if (aNumber < 0) {
            return aNumber * 7 - 5.2;
        }
        else {
            return aNumber * 78 + 9.3;
        }
    }
}

class B {
    boolean status = true;

    Float function opearationB(int: theNumber){
        if(status == true){
            return a.operationA(aNumber);
        }
    }
}

In order to correctly test A.operationA(), I would have to write at least three unit tests (aNumber = 0, aNumber > 0 and aNumber < 0).

Now let's say I want to test B.functionB, using black-box strategy, should I re-write the similar three unit tests (theNumber= 0, theNumber> 0 and theNumber< 0) ? In that case, I would have to create a lot of tests each time I use the method A.operationA ...


Solution

  • If the black box constraint can be loosened you can remove all the duplication. I really like Jay Fields definitions of solitary vs sociable unit tests, explained here.

    It should be trivial to test class A in isolation. It has no side effects and no collaborators. Ideally class B could also be tested in isolation (solitary) where it's collaborator's, class a, is stubbed out. Not only does this let you exercise class B in isolation, it helps control cascading failures. If class B is tested with the real life class A when class A changes it could cause a failure in class B.

    At some point collaboration (sociable) should probably be checked, a couple ways may be:

    • a single socialable test that calls b through its public interface and triggers the default case in class A
    • Higher level tests that exercise a specific user story or external flow path, which triggers class B

    Sorry didn't answer your direct question.