mirror of
https://github.com/corda/corda.git
synced 2024-12-28 16:58:55 +00:00
f0138dfe17
* Moves code sections in tutorials to code files. * Removes wallet references. * Updates repo layout doc. * Removes remaining cordapp-tutorial references, replaced with cordapp-example. * Fixes broken link. * Misc docs fixes. * Refreshes the ServiceHub and rpc ops api pages. * Updates the cheat sheet. * Updates cookbooks. * Refreshes the running-a-notary tutorial. * Updates flow-testing tutorial * Updates tear-offs tutorial. * Refreshes integration-testing tutorial. * Updates to contract tutorial and accompanying code to bring inline with V1 release. * Refreshes contract-upgrade tutorial. * Fixed broken code sample in "writing a contract" and updated contracts dsl. * Added contract ref to java code. Fixed broken rst markup. * Updates transaction-building tutorial. * Updates the client-rpc and flow-state-machines tutorials. * Updates the oracles tutorial. * Amended country in X500 names from "UK" to "GB" * Update FlowCookbook.kt * Amended cheatsheet. Minor update on contract upgrades tutoraial. * Added `extraCordappPackagesToScan` to node driver. * Changes to match new function signature. * Update to reflect change in location of cash contract name.
71 lines
3.9 KiB
ReStructuredText
71 lines
3.9 KiB
ReStructuredText
.. highlight:: kotlin
|
|
.. raw:: html
|
|
|
|
<script type="text/javascript" src="_static/jquery.js"></script>
|
|
<script type="text/javascript" src="_static/codesets.js"></script>
|
|
|
|
Writing flow tests
|
|
==================
|
|
|
|
A flow can be a fairly complex thing that interacts with many services and other parties over the network. That
|
|
means unit testing one requires some infrastructure to provide lightweight mock implementations. The MockNetwork
|
|
provides this testing infrastructure layer; you can find this class in the test-utils module.
|
|
|
|
A good example to examine for learning how to unit test flows is the ``ResolveTransactionsFlow`` tests. This
|
|
flow takes care of downloading and verifying transaction graphs, with all the needed dependencies. We start
|
|
with this basic skeleton:
|
|
|
|
.. literalinclude:: ../../core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt
|
|
:language: kotlin
|
|
:start-after: DOCSTART 3
|
|
:end-before: DOCEND 3
|
|
|
|
We create a mock network in our ``@Before`` setup method and create a couple of nodes. We also record the identity
|
|
of the notary in our test network, which will come in handy later. We also tidy up when we're done.
|
|
|
|
Next, we write a test case:
|
|
|
|
.. literalinclude:: ../../core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt
|
|
:language: kotlin
|
|
:start-after: DOCSTART 1
|
|
:end-before: DOCEND 1
|
|
:dedent: 4
|
|
|
|
We'll take a look at the ``makeTransactions`` function in a moment. For now, it's enough to know that it returns two
|
|
``SignedTransaction`` objects, the second of which spends the first. Both transactions are known by MegaCorpNode but
|
|
not MiniCorpNode.
|
|
|
|
The test logic is simple enough: we create the flow, giving it MegaCorpNode's identity as the target to talk to.
|
|
Then we start it on MiniCorpNode and use the ``mockNet.runNetwork()`` method to bounce messages around until things have
|
|
settled (i.e. there are no more messages waiting to be delivered). All this is done using an in memory message
|
|
routing implementation that is fast to initialise and use. Finally, we obtain the result of the flow and do
|
|
some tests on it. We also check the contents of MiniCorpNode's database to see that the flow had the intended effect
|
|
on the node's persistent state.
|
|
|
|
Here's what ``makeTransactions`` looks like:
|
|
|
|
.. literalinclude:: ../../core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt
|
|
:language: kotlin
|
|
:start-after: DOCSTART 2
|
|
:end-before: DOCEND 2
|
|
:dedent: 4
|
|
|
|
We're using the ``DummyContract``, a simple test smart contract which stores a single number in its states, along
|
|
with ownership and issuer information. You can issue such states, exit them and re-assign ownership (move them).
|
|
It doesn't do anything else. This code simply creates a transaction that issues a dummy state (the issuer is
|
|
``MEGA_CORP``, a pre-defined unit test identity), signs it with the test notary and MegaCorp keys and then
|
|
converts the builder to the final ``SignedTransaction``. It then does so again, but this time instead of issuing
|
|
it re-assigns ownership instead. The chain of two transactions is finally committed to MegaCorpNode by sending them
|
|
directly to the ``megaCorpNode.services.recordTransaction`` method (note that this method doesn't check the
|
|
transactions are valid) inside a ``database.transaction``. All node flows run within a database transaction in the
|
|
nodes themselves, but any time we need to use the database directly from a unit test, you need to provide a database
|
|
transaction as shown here.
|
|
|
|
With regards to initiated flows (see :doc:`flow-state-machines` for information on initiated and initiating flows), the
|
|
full node automatically registers them by scanning the CorDapp jars. In a unit test environment this is not possible so
|
|
``MockNode`` has the ``registerInitiatedFlow`` method to manually register an initiated flow.
|
|
|
|
And that's it: you can explore the documentation for the
|
|
`MockNetwork API <api/kotlin/corda/net.corda.testing.node/-mock-network/index.html>`_
|
|
here.
|