This is an automated archive.

The original was posted on /r/golang by /u/steadyneighborhood90 on 2023-08-08 21:10:07+00:00.


Let’s say I’m writing some tests for code which makes a cup of coffee:

func MakeCoffee(c CoffeeJar, g Grinder, m Machine) (*Drink, error) {
    // 1
    beans, err := c.ScoopBeans()
    if err != nil {
        return nil, err
    }
    // 2
    dose, err := g.Grind(beans)
    if err != nil {
        return nil, err
    }
    // 3
    err = m.EnsureWater()
    if err != nil {
        return nil, err
    }
    // 4
    drink, err := m.MakeCoffee(dose)
    if err != nil {
        return nil, err
    }
    return drink, nil
}

Testing the happy path is straightforward but testing individual error cases can require a lot of plumbing.

For example, testing #3 requires 1 & 2 to be set up in a specific way and testing #4 requires 1, 2 & 3 to be set up in a specific way… and I find this makes the tests fragile: a small change to a dependency can cause a number of tests to fail. And it gets worse if I want to add calls to FrothMilk() and AddChocolateSprinkles(), which themselves return errors.

I’ve spent a lot of time writing tests like this, but I’ve starting to think they’re not actually adding much value to my project. Given the code is literally just returning the error to the caller (or something equally basic), should I even bother testing these scenarios?

Any advice appreciated