Unit testing constructor injection
Asked Answered
D

2

9

Suppose that my Foo class has the following:

readonly IService service;

public Foo(IService service) 
{
    if (service == null)
        throw new ArgumentNullException("service");

    this.service = service;
}

public void Start()
{
    service.DoStuff();
}

So far, I have one unit test for the constructor where I pass in null to verify that an ArgumentNullException gets thrown. Do I need a second unit test for my constructor where I pass in a valid IService and verify that this.service gets set (which would require a public accessor)?

Or should I just rely on my unit test for the Start method to test this code path?

Dendroid answered 1/4, 2013 at 20:47 Comment(0)
S
12

Setting this.service is an implementation detail, so you should just be testing that it is used where expected and just test this via the Start method. Lest your tests become brittle.

You only want to test that your service is used appropriately. You shouldn't care how it is stored.

Spiculum answered 1/4, 2013 at 20:49 Comment(0)
C
10

These tests are redundant, since no other test will succeed when your constructor doesn't work.

And to be honest, I don't even bother to write those null checks in my constructors anymore. Reason is simple: DI containers don't allow you to auto-wire constructors with null references (or at least, not by default), so there is no possibility of types being constructed using null values (when auto-wired by a container). So it just adds useless code that makes me add useless tests when I want to have high code coverage.

I say skip these null checks completely and trust your DI container (or pick a DI container that you can trust).

Conformation answered 1/4, 2013 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.