Contract Testing

The Contract Testing library enables CorDapp Corda Distributed Application. A Java (or any JVM targeting language) application built using the Corda build toolchain and CorDapp API to solve some problem that is best solved in a decentralized manner. developers to test smart contracts locally at an early stage of the development cycle. With this library, you can check that your CorDapp contracts behave as expected before, or after, you write the flows.

The Contract Testing library is currently compatible with the following versions of Corda:

  • 5.0
  •  CSDE CorDapp Standard Development Environment. The recommended developer environment setup for developers wishing to write Corda 5 CorDapps. — contains Contract Testing library examples.
  • Contract and state classes

To import the library to your CorDapp, add it to your contracts build.gradle dependencies:

testImplementation "com.r3.corda.ledger.utxo:contract-testing:1.0.0”

If you are using Kotlin, you can also add the Kotlin DSL:

testImplementation "com.r3.corda.ledger.utxo:contract-testing-kotlin:1.0.0”

You can now extend the ContractTest interface to create a test class for your smart contracts.

All tests should extend ContractTest as a starting point. The ContractTest class provides functions to easily write contract tests, the UTXOLedgerService and MockSigningService classes, and also some useful test data:

X.500 Legal IdentitiesPublic Keys
aliceNamealiceKey
bobNamebobKey
charlieNamecharlieKey
daveNamedaveKey
eveNameeveKey
bankANamebankAKey
bankBNamebankBKey
notaryNamenotaryKey

If you expect your test to pass the contract validation, use assertVerifies. For example:

@Test
public void happyPath() {
    // Create a UTXO transaction on the ledger passing in valid contract arguments
    UtxoSignedTransaction transaction = getLedgerService()
        .createTransactionBuilder()
        .addInputState(inputState)
        .addOutputState(outputState)
        .addCommand(new MyContract.MyCommand())
        .addSignatories(List.of(bankAKey, bankBKey, notaryKey))
        .toSignedTransaction();
    // Validate the output transaction is successful
    assertVerifies(transaction);
}

The buildTransaction function creates a UtxoLedgerTransaction that contract tests can reference. The assertVerifies function tests if a contract test passes or fails. If the transaction is verified, the contract tests pass.

If you expect the contract validation to reject the transaction, make use of assertFailsWith. For example:

@Test
public void negativePath() {
    // Create a UTXO transaction on the ledger passing in invalid contract arguments
    UtxoSignedTransaction transaction = getLedgerService()
        .createTransactionBuilder()
        .addInputState(invalidInputState)
        .addOutputState(outputState)
        .addCommand(new MyContract.MyCommand())
        .addSignatories(List.of(bankAKey, bankBKey, notaryKey))
        .toSignedTransaction();
    // Validate that the output transaction fails with a specific validation error message 
    assertFailsWith(transaction, "Validation message here");
}

The assertFailsWith function tests for unhappy-path contract tests. The assertFailsWith method tests if the exact string of the error message matches the expected message. To test if the string of the error message contains a substring, use the assertFailsWithMessageContaining function using the same arguments.

The CSDE contains Contract Testing examples in the following locations:

The apples example tests the AppleStampContract and BasketOfApplesContract contracts written as part of the Building Your First CorDapp tutorial.

The utxoexample example tests the ChatContract of the UTXO chat application delivered with the CSDE.

Was this page helpful?

Thanks for your feedback!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.

We're sorry this page wasn't helpful. Let us know how we can make it better!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Create an issue

Create a new GitHub issue in this repository - submit technical feedback, draw attention to a potential documentation bug, or share ideas for improvement and general feedback.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.