2

I am currently writing unit test for my Solana contract written using the Anchor framework. I have created unit tests for the positive flow of how things should work, and all the tests are passing, but I cannot find any documentation on how to ensure that a certain transaction should fail (i.e. due to improper inputs or signature errors)

Does anyone have any resources where I can learn more about this, or if this is even possible with the current Anchor framework?

3 Answers 3

2

Suppose you have your rust code like this

pub fn call(ctx: Context<Call>) -> Result<()>
{
   return Err(CallError::ErrorExpected.into())
}

pub struct Call<'info>
{
  #[account(mut)]
  pub from: Signer<'info>,
  
  pub to: AccountInfo<'info>,
}

#[error_code]
pub enum CallError 
{
    #[msg("An Error Occured")]
    ErrorExpected,
}

You can test for errors on client side like this

try{
  await program.methods
     .call()
     .accounts({
       from: provider.publicKey,
       to: toAccount.publicKey
     })
     .signers([])
     .rpc()
}
catch (error) {
      const errMsg = "An Error Occured";
      assert.equal((error as AnchorError).error.errorMessage, errMsg)
}
1

you can assert the error logs:

it("Does not allow creating a pixel out of bounds", async () => {
    const x = 0
    const y = 200
    const [pixelPublicKey] = web3.PublicKey.findProgramAddressSync(
      [Buffer.from("pixel"), Buffer.from([x, y])],
      program.programId,
    )

    await program.methods
      .createPixel(x, y, 0, 0, 255)
      .accounts({
        pixel: pixelPublicKey,
        user: anchorProvider.wallet.publicKey,
        systemProgram: web3.SystemProgram.programId,
      })
      .rpc()
      .then(
        () => Promise.reject(new Error('Expected to error!')),
        (e: AnchorError) => {
          assert.ok(e.errorLogs.some(log => log.includes('InvalidYCoordinate') && log.includes('The given Y co-ordinate is not between 0-99.')))
        }
      );
  })
1

This is my code. It works well.

try {
  ...
} catch(error) {
  const errMsg = error.error?.errorMessage ? error.error?.errorMessage : anchor.AnchorError.parse(error.logs).error.errorMessage;
  assert.equal(errMsg, "ERROR MESSAGE HERE!");
}
1
  • Thanks, let me try it!
    – michaelb
    Commented May 8 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.