A Different Unit Test Pattern

bob.ts - Sep 3 '19 - - Dev Community

I will be adding this pattern to Bad Test, Bad

A Unit Testing Anti-Pattern

This test is a pattern that I haven't seen before ... where the setup and initiator for the test is in a nested beforeEach and the individual expects are each within their own test.

When I first looked at this code I thought, "this is cool."

Then, I very quickly got an odd, queasy feeling ...

  • If this pattern was so cool, why haven't I seen this pattern somewhere before?
  • Why would a developer have created this pattern?
describe("removeSomething", function () {
  describe("where when called", function () {
    beforeEach(function () {
      this.module.remove.and.returnValue(jasmine.helpers.deferredDone());
      this.module.removeSomething();
    });

    it("should call remove action to remove something", function () {
      expect(this.module.remove).toHaveBeenCalledWith({
        "subPathId": "removeSomething"
      });
    });
  });
});
Enter fullscreen mode Exit fullscreen mode

The first thing that came to mind is that someone had been taught to only create one expect per test and this pattern allowed that for the individual execution of the code-under-test. This pattern allows a developer to ignore the Single Responsibility Principle (SRP) for the code-under-test and write what looks like good tests.

Conclusion

For this specific set of code, I found that the original code could be tested by simply moving the beforeEach code above into the test. But here, the point is that the pattern should not have been used. While it is elegant "in a way," it also makes for a convoluted setup and initiation of a test that can allow for a more complex pattern of code-under-test that breaks the Single Responsibility Principle.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .