DEV Community

loading...
Cover image for πŸ– 5 TDD Most Common Mistakes

πŸ– 5 TDD Most Common Mistakes

Abdulcelil Cercenazi
I enjoy learning and teaching, I am currently working as a Software developer using Spring and Vanilla JavaScript.
・2 min read

If you are using TDD, as you should be 🀨, you have been a victim of at least one of those anti-patterns.

We will discuss 5 πŸ– of them, looking at their Causes, Problems and how to avoid them.


1️⃣ The Liar πŸ€₯

Passes all tests with no useful assertions

  • Causes
    • Chasing test coverage
  • Problem
    • Illusiuon of coverage
    • Waste of time and money
  • Correction
    • Delete the tests
    @Test
    public void liarTest(){
        ShipmentService shipmentService = new ShipmentService();
        shipmentService.doStuff();
        assertTrue(true);
    }
Enter fullscreen mode Exit fullscreen mode

2️⃣ Excessive Setup 🧰

Requires a lot of work to prepare the test

  • Causes
    • Poor modularity and poor separation of concerns in the design
  • Problem
    • Tests and code are highly coupled
    • Hard to maintain
    • This will slow down the development to a halt
  • Correction
    • Improve abstraction and separation of concerns in the code
    • Write pure functions
    @Test
    public void excessiveSetup (){
        // set up beginning
        VerificationService verificationService = new VerificationService();
        ShipmentRepository shipmentRepository = new ShipmentRepository();
        ShipmentService shipmentService = new ShipmentService(verificationService, shipmentRepository);

        Product product = new Product("Product");
        Owner owner = new Owner("owner");
        Count count = new Count(100);
        Shipment shipment = new Shipment(product, owner, count);
        ShipmentDetail shipmentDetail = new ShipmentDetail(shipment);
        // set up ending

        // rest of test
    }
Enter fullscreen mode Exit fullscreen mode

3️⃣ The Giant πŸ’₯

Has multiple assertions in a single test

  • Causes
    • Testing too much things at the same time
  • Problem

    • Hard to understand
    • Test and code are highly coupled
    • Hard to maintain
  • Correction

    • Decompse the test into multiple tests
    @Test
    public void theGiant (){
        ShipmentService shipmentService = new ShipmentService();

        Shipment shipment = new Shipment("product", "owner", 2);
        shipmentService.processShipment_Free(shipment);
        assertEquals("productUpdated", shipment.getProduct());
        assertEquals("ownerUpdated", shipment.getOwner());
        assertEquals(5, shipment.getCount());

        Shipment shipment2 = new Shipment("product2", "owner2", 9);
        shipmentService.processShipment_Premium(shipment);
        ssertEquals("productPremium", shipment2.getProduct());
        assertEquals("ownerPremium", shipment2.getOwner());
        assertEquals(41, shipment2.getCount());

        // could go on even further
        //....
    }
Enter fullscreen mode Exit fullscreen mode

4️⃣ The Mockery 🀑

Uses so many mocks that the real code isn't tested

  • Causes

    • Excessive setup
  • Problems

    • Doesn't test anything
  • Correction

    • Review code design
    • Improve abstraction and seperation of concerns
    @Test
    public void theMockery (){
        doReturn("test").when(serviceMock).getValue();
        doReturn(true).when(serviceMock).isValid();

        assertEquals("test", serviceMock.getValue());
        assertTrue(serviceMock.isValid());
    }
Enter fullscreen mode Exit fullscreen mode

5️⃣ The inspector 🧐

Adding functions that are only used in the tests

  • Causes

    • Chasing test coverage
  • Problems

    • Waste of time and money since it doesn't test production code
  • Corrections

    • Delete those functions.

The source of this information is mainly from this amazing YouTube video.

Discussion (0)