# carlin

`software.visionary.spex:carlin:2026.10.13` · https://codeberg.org/spectacular/carlin

Test doubles for Java: stubbed answers and verified calls.

Creates test doubles, supplies their answers and verifies calls made to them.

## Key Concepts

### Stubbing

**Role.** <code>Doubles.mock</code> accepts interfaces and extensible classes. Unstubbed calls return zero, false, supported empty containers or null. Use <code>Doubles.stub(call)</code> for successive return values, exceptions or computed answers; the final answer repeats. An <code>Answer</code> states the answer before the call, for void methods or restubbing without executing an existing answer: <code>returning</code>, <code>throwing</code>, <code>answering</code>, <code>nothing</code> or <code>real</code>, then <code>of(double).call()</code>.

### Arguments and verification

**Role.** Arguments match by value, with arrays compared by contents. If one argument uses an <code>Argument</code> matcher, all must: use <code>eq</code> for literal values. <code>any()</code> includes null; typed matchers do not. A <code>confirmation.Confirmation</code> is the receiver, as an <code>Answer</code> is: <code>once().of(double).call()</code> confirms the call made on what <code>of</code> returns and throws <code>Braindropping</code> on mismatch. A <code>Frequency</code> (<code>once</code>, <code>times</code>, <code>never</code>, <code>atLeastOnce</code>, <code>atMost</code>) confirms how often the call was made. Stubbing and confirmation expressions do not count as calls.

### Order, capture and waiting

**Role.** <code>Confirmation.ordered(doubles)</code> is the <code>Ordered</code> confirmation: each <code>of(double).call()</code> must have been made after the one confirmed before it. <code>Capturer.capturer</code> retains matched arguments. <code>Timeout.timeout(milliseconds)</code> gives a <code>Frequency</code> that waits: <code>once()</code> or <code>atLeast(n)</code>. <code>Confirmation.noInteractions</code> requires no calls; <code>noMoreInteractions</code>, on <code>Confirmation</code> for doubles or on an <code>Ordered</code>, requires every call to have been confirmed.

## Usage

Stub a lookup and verify a write

```java
import software.visionary.carlin.Capturer;
import static software.visionary.carlin.Doubles.mock;
import static software.visionary.carlin.Doubles.stub;
import static software.visionary.carlin.Answer.real;
import static software.visionary.carlin.confirmation.Confirmation.noMoreInteractions;
import static software.visionary.carlin.confirmation.Frequency.once;

public class DoubleExample {
    public interface Shelf {
        String titleAt(int index);
        void shelve(String title);
        default String first() { return titleAt(0); }
    }
    public static void main(String[] args) {
        Shelf shelf = mock(Shelf.class);
        stub(shelf.titleAt(0)).returning("First").returning("Second");
        real().of(shelf).first();
        System.out.println(shelf.first());
        shelf.shelve("Book");
        var title = Capturer.capturer(String.class);
        once().of(shelf).shelve(title.capture());
        System.out.println(title.value());
        once().of(shelf).first();
        once().of(shelf).titleAt(0);
        noMoreInteractions(shelf);
    }
}

```

## Dependencies

- `software.visionary.contrax:enforcements:2026.10.13` at Provided
- `software.visionary:junit-closure:2026.10.13` at Testing

## Caveats

- Final, sealed, record, enum, primitive and array types cannot be doubled. A class double runs its public or protected constructor with the fewest parameters, using zero and null arguments; final methods execute real code. Real default methods require a public interface in an accessible package. <code>Answer.real</code> supports interface defaults only.

