DEV Community

Cover image for A Different Unit Test Pattern
bob.ts
bob.ts

Posted on • Updated on

A Different Unit Test Pattern

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.

Top comments (4)

Collapse
 
eljayadobe profile image
Eljay-Adobe • Edited

When I was doing C# programming (using the TDD process, NUnit and NCrunch), our unit tests followed the WET principle.

"Write Explicit Tests", which meant the unit tests should test one-and-only-one thing, should not have branches or loops, and do not have a communal set-up and tear-down code. Each unit test is responsible for the entirety of its Arrange-Act-Assert sections.

DRY is great for the code under test, but not for unit tests themselves. WET is much better.

My former co-worker Arlo Belshee wrote up a nice blog post about DRY & WET: arlobelshee.com/wet-when-dry-doesn...

Collapse
 
rfornal profile image
bob.ts

Exactly ... the code I presented abstracted put the Arrange and Act portions of the tests. I strongly suspect this was to adhere to the single Assert so tightly, they lost focus on what actually needed to be accomplished ... adjusting the code-under-test to make it more testable.

Collapse
 
rfornal profile image
bob.ts

I should also mention that I read the article you included ... great stuff: arlobelshee.com/wet-when-dry-doesn...

Collapse
 
peerreynders profile image
peerreynders • Edited

If this pattern was so cool, why haven't I seen this pattern somewhere before?

My interpretation is that this is an implementation of the Fresh Fixture xUnit pattern - documented even before 2007 when xUnit Test Patterns: Refactoring Test Code was published.

See also: Principle: Verify One Condition per Test