Skip to content

// Testing · 02

Arrange-Act-Assert

Arrange inputsleads toAct onceleads toAssert outcome

Set up, do one thing, check one outcome. Name what it proves.

How it fits together

Arrange-Act-Assert structureArrangebuild the inputsfake the outsideActone callonly the system under testAssertcheck the resultno more calls1 build input2 call once
uses / calls· numbered steps replay in order
  • Arrange uses / calls Act (1 build input)
  • Act uses / calls Assert (2 call once)

Spot it

  • Test names like Test1 or Works
  • One test checks five unrelated behaviours
  • A failing test does not say what broke

It costs

More test methods, each shorter and clearer, so the test file grows.

In code

public sealed class PriceCalculatorTests{    [Fact]    public void Total_WithTwoLines_SumsLinePrices()    {        // Arrange        var lines = new[] { new OrderLine("pen", 2, 1.50m), new OrderLine("pad", 1, 4.00m) };        var calculator = new PriceCalculator();​        // Act        var total = calculator.Total(lines);​        // Assert        total.ShouldBe(7.00m);    }}
Go deeperThe full explanation and what to ask for · 1 min readExpand

Arrange-Act-Assert, often written Given-When-Then, splits a test into three blocks: set up the state, perform one action, check the outcome. The blocks make the intent visible. A reader should see the input, the trigger and the expectation without tracing helper methods.

One act per test keeps failures specific. If a test calls the method twice, a failure does not say which call broke, and the second call may depend on side effects of the first. Asserting many unrelated facts has the same problem: the first failed check hides the rest. Several assertions about one result are fine, because they describe one behaviour.

Name the test after the behaviour so a failure reads like a sentence. Keep the arrange block to what the behaviour depends on; a setup of fifty lines usually means too many collaborators, or a builder that would hide the noise. When NOT to: an integration test of a multi-step workflow may need several acts, but each step should still be checked explicitly.

Ask for it

  • arrange
  • act
  • assert
  • one behaviour per test
  • Method_Condition_Result
  • system under test

Rewrite the pricing tests so each checks one behaviour, named Method_Condition_Result (for example Total_WithTwoLines_SumsLinePrices). Each test has an arrange block, exactly one call to the method under test, and assertions only on what that call returned.