Skip to content
Discussions/App Development/Asserting Errors in Unit Test when thrown in a choiceForum ↗

Asserting Errors in Unit Test when thrown in a choice

App Development2 posts191 views1 likesLast activity Dec 2022
GT
gtpaulose2OP
Dec 2022

Given the following choice,

 choice SetAge: ()
      with
        age: Decimal
      controller owner
        do
          if age == 0 
          then error("Age cannot be 0") 
          else create this with age = age

I want to explicitly test in my UT (daml script) that the error, “Age cannot be 0”. How would i do that?

Or another way to frame my question is how do i get access to exceptions thrown by choices in Daml script so that i can do assertions upon them?

A_
a_putkov
Dec 2022

The Exception Handling section in Daml documentation discusses two options for handling exceptions: using Either data type and using try-catch block. For your use case you need to utilize both.
Here’s an example with a custom exception.

exception ZeroAge
  where
    message "Age cannot be zero"

template Student
  with
    age : Decimal
    name : Text
    school : Party
  where
    signatory school

    choice SetAge : ContractId Student
      with
        newage : Decimal
      controller school
      do
        if newage == 0.0
        then throw ZeroAge 
        else create this with age = newage

template TestHelper 
  with
    tester : Party
  where
    signatory tester

    nonconsuming choice Test_SetAge : Either Text Text
      with
        studentCid : ContractId Student
        newage : Decimal
      controller tester
      do
        try do
          exercise studentCid SetAge with newage
          return $ Right "Success"
        catch 
          (ex : ZeroAge) -> do
            return $ Left $ message ex

testSetAge = script do
  hs1 <- allocateParty "High School 1"
  alice_studentCid <- submit hs1 do
    createCmd Student with
      age = -1.0
      name = "Alice"
      school = hs1
  thCid <- submit hs1 do
    createCmd TestHelper with
      tester = hs1
  test_result <- submit hs1 do
    exerciseCmd thCid Test_SetAge with 
      studentCid = alice_studentCid
      newage = 0.0
  test_result === Left "Age cannot be zero"
  return ()

Note that, because exceptions are not propagated across submit, you cannot catch the exception thrown by SetAge choice in a try-catch block in Daml Script, and you need to utilize a helper template to catch the exception. For details on why this is the case and some additional examples check out previous discussions on the following threads

I’m trying to handle an inbuilt exception in a Script. Using the getting-started User example, I’ve written this test, trying to handle an assertion failure and just log the error message: my_test : Script () my_test = script do alice <- allocateParty "Alice" bob <- allocateParty "Bob" aliceUserCid <- submit alice do createCmd User with username = alice; following = [] bobUserCid <- submit bob do createCmd User with username = bob; following = [] aliceUserCid <- submit alice…
Hey team, I’m writing some scripts to test some new features I’ve recently added to a Daml project. One thing I noticed is when I do negative testing, using submitMustFail that I’d like to also provide the reason why the submission should fail. Currently, I have to manually check that the submission failed as I cannot specify the reason why the submission should fail. For example, I have choices that requires multiple signatures with multiple assertions. I cannot distinguish a failure on a mis…
← Back to Discussions