Skip to content

Write tests, mock collaborators, and pin a `Mock[T]`

Goal: write and run tests, assert outcomes, fabricate values, and replace a dependency.

Tests live in a project’s tests/ tree (see Lay out a project). A test file is a test block naming its target unit, containing named cases.

test counters {
test "a fresh counter starts at zero" {
let n <- Counter(CounterId.unsafe("fresh")).current()
assert n == 0
}
}

Run the suite:

Terminal window
bynkc test .

bynkc test compiles the project, type-checks it with tsc, and runs it with Node, so both must be on your path. assert is valid only inside a test case.

Mock[T] produces a value of T. For a refined type it satisfies the refinement; pass an argument to pin a specific value:

test quantities {
test "mocks" {
let a = Mock[Quantity] -- a valid Quantity
let b = Mock[Quantity](50) -- pinned to 50
assert a == a
assert b == b
}
}

A Matches-refined string cannot be fabricated blindly — a bare Mock of one is rejected (bynk.mock.needs_pin); pin it instead. Mock[T] is test-only.

Replace a capability the code under test depends on:

test payments {
mocks Logger = SilentLogger {
fn log(msg: String) -> Effect[()] {
()
}
}
test "authorise succeeds for a positive amount" {
let r <- authorise.call(100)
assert r is Ok(_)
}
}

The SilentLogger stands in for the real Logger for these cases.