liveBook · Manning

Constructor method

As explained in Unit Testing Principles, Practices, and Patterns

A constructor is a class member invoked when an object is created to initialize its state.

A constructor is a class member invoked when an object is created to initialize its state. In tests, putting shared fixture setup in a constructor reduces repetition but couples every test to the same arrangement. section 3.3 section 11.1

Prefer arrangements that preserve independent modification and readable tests:

  • Avoid placing test-specific fixture setup in the test class constructor; changing one arrangement can invalidate unrelated tests. section 3.3
  • Extract genuinely common setup into private factory methods so each test states its own arrangement explicitly. section 3.3
  • Use a base-class constructor for genuinely shared integration infrastructure, such as creating and disposing a database. section 3.3
  • Treat private constructors by purpose: avoid testing implementation details, but preserve contracts required by an ORM or encapsulation. section 11.1

Refactoring shared test setup

Replace constructor-owned state such as `_store` and `_sut` with local arrangements: `Store store = CreateStoreWithInventory(Product.Shampoo, 10);` and `Customer sut = CreateCustomer();`. Each test then exposes its assumptions while retaining reusable construction logic. section 3.3

Listing 3.7. Extracting the initialization code into the test constructor
public class CustomerTests
{
    private readonly Store _store;                  #1
    private readonly Customer _sut;

    public CustomerTests()                          #2
    {                                               #2
        _store = new Store();                       #2
        _store.AddInventory(Product.Shampoo, 10);   #2
        _sut = new Customer();                      #2
    }                                               #2

    [Fact]
    public void Purchase_succeeds_when_enough_inventory()
    {
        bool success = _sut.Purchase(_store, Product.Shampoo, 5);

        Assert.True(success);
        Assert.Equal(5, _store.GetInventory(Product.Shampoo));
    }

    [Fact]
    public void Purchase_fails_when_not_enough_inventory()
    {
        bool success = _sut.Purchase(_store, Product.Shampoo, 15);

        Assert.False(success);
        Assert.Equal(10, _store.GetInventory(Product.Shampoo));
    }
}

Shows the fragile pattern of initializing a store and system under test in the test constructor. section 3.3

Listing 11.3. A class with a private constructor
public class Inquiry
{
    public bool IsApproved { get; private set; }
    public DateTime? TimeApproved { get; private set; }

    private Inquiry(                                 #1
        bool isApproved, DateTime? timeApproved)     #1
    {
        if (isApproved && !timeApproved.HasValue)
            throw new Exception();

        IsApproved = isApproved;
        TimeApproved = timeApproved;
    }

    public void Approve(DateTime now)
    {
        if (IsApproved)
            return;

        IsApproved = true;
        TimeApproved = now;
    }
}

Shows a private constructor enforcing the invariant that approved inquiries require an approval time. section 11.1

How Unit Testing Principles, Practices, and Patterns covers it

How deep it goes
Compares constructor-based setup with factory methods and base classes, then examines private-constructor contracts; stops short of language semantics.
Examples
Uses CustomerTests fixture setup, factory-method refactoring, integration-test database setup, and an Inquiry private constructor.
What it assumes
Assumes basic object-oriented classes and unit testing while defining test fixtures, test isolation, and observable behavior through examples.
What you can do after
Diagnose constructor-based test coupling and choose explicit factories or shared infrastructure without exposing unnecessary implementation details.
How it connects
Connects constructors with test fixtures, test isolation, implementation details, encapsulation, observable behavior, ORM, and reflection.

Also explained in

Compare how 13 books explain constructor method →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Unit Testing Principles, Practices, and Patterns. The section links point to the parts of the book it draws on.