Unit testing for canisters
The Tester
class in this module can be used to define unit tests for canisters.
public func should(name : Text, test : () -> async TestResult)
Registers a test. You can use attempt
to use a Matcher
to
produce a TestResult
.
public func shouldFailTo(name : Text, test : () -> async ())
Registers a test that should throw an exception.
public func runAll() : async Text
Runs all your tests in one go and returns a summary Text. If calling
this runs out of gas, try using run
with a configured batchSize
.
public func run() : async Protocol
You must call this as the last thing in your unit test.
Instantiate one of these on canister initialization. Then you can use it to register your tests and it will take care of running them.
Use runAll
for simple setups and run
once that stops working.
When using run
the Tester
will execute your tests in the right batch
sizes. It will keep calling your test
function over and over, so make sure
to not do any work outside the registered tests.
import Canister "canister:YourCanisterNameHere";
import C "mo:matchers/Canister";
import M "mo:matchers/Matchers";
import T "mo:matchers/Testable";
actor {
let it = C.Tester({ batchSize = 8 });
public shared func test() : async Text {
it.should("greet me", func () : async C.TestResult = async {
let greeting = await Canister.greet("Christoph");
M.attempt(greeting, M.equals(T.text("Hello, Christoph!")))
});
it.shouldFailTo("greet him-whose-name-shall-not-be-spoken", func () : async () = async {
let greeting = await Canister.greet("Voldemort");
ignore greeting
});
await it.runAll()
// await it.run()
}
}