mirror of
https://github.com/corda/corda.git
synced 2025-02-21 09:51:57 +00:00
CORDA-2345: Updated docs to use the new TestCordapp API, rather than the old scan cordapp packages (#4491)
Also made some improvements to the API, especially for Java users.
This commit is contained in:
parent
ad1a96fefb
commit
f590300cdf
@ -311,70 +311,6 @@ For example:
|
|||||||
For Contracts that are annotated with ``@NoConstraintPropagation``, the platform requires that the Transaction Builder specifies
|
For Contracts that are annotated with ``@NoConstraintPropagation``, the platform requires that the Transaction Builder specifies
|
||||||
an actual constraint for the output states (the ``AutomaticPlaceholderConstraint`` can't be used) .
|
an actual constraint for the output states (the ``AutomaticPlaceholderConstraint`` can't be used) .
|
||||||
|
|
||||||
|
|
||||||
Testing
|
|
||||||
-------
|
|
||||||
|
|
||||||
Since all tests involving transactions now require attachments it is also required to load the correct attachments
|
|
||||||
for tests. Unit test environments in JVM ecosystems tend to use class directories rather than JARs, and so CorDapp JARs
|
|
||||||
typically aren't built for testing. Requiring this would add significant complexity to the build systems of Corda
|
|
||||||
and CorDapps, so the test suite has a set of convenient functions to generate CorDapps from package names or
|
|
||||||
to specify JAR URLs in the case that the CorDapp(s) involved in testing already exist. You can also just use
|
|
||||||
``AlwaysAcceptAttachmentConstraint`` in your tests to disable the constraints mechanism.
|
|
||||||
|
|
||||||
MockNetwork/MockNode
|
|
||||||
********************
|
|
||||||
|
|
||||||
The simplest way to ensure that a vanilla instance of a MockNode generates the correct CorDapps is to use the
|
|
||||||
``cordappPackages`` constructor parameter (Kotlin) or the ``setCordappPackages`` method on ``MockNetworkParameters`` (Java)
|
|
||||||
when creating the MockNetwork. This will cause the ``AbstractNode`` to use the named packages as sources for CorDapps. All files
|
|
||||||
within those packages will be zipped into a JAR and added to the attachment store and loaded as CorDapps by the
|
|
||||||
``CordappLoader``.
|
|
||||||
|
|
||||||
An example of this usage would be:
|
|
||||||
|
|
||||||
.. sourcecode:: java
|
|
||||||
|
|
||||||
class SomeTestClass {
|
|
||||||
MockNetwork network = null;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
void setup() {
|
|
||||||
network = new MockNetwork(new MockNetworkParameters().setCordappPackages(Arrays.asList("com.domain.cordapp")))
|
|
||||||
}
|
|
||||||
|
|
||||||
... // Your tests go here
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MockServices
|
|
||||||
************
|
|
||||||
|
|
||||||
If your test uses a ``MockServices`` directly you can instantiate it using a constructor that takes a list of packages
|
|
||||||
to use as CorDapps using the ``cordappPackages`` parameter.
|
|
||||||
|
|
||||||
.. sourcecode:: java
|
|
||||||
|
|
||||||
MockServices mockServices = new MockServices(Arrays.asList("com.domain.cordapp"))
|
|
||||||
|
|
||||||
However - there is an easier way! If your unit tests are in the same package as the contract code itself, then you
|
|
||||||
can use the no-args constructor of ``MockServices``. The package to be scanned for CorDapps will be the same as the
|
|
||||||
the package of the class that constructed the object. This is a convenient default.
|
|
||||||
|
|
||||||
Driver
|
|
||||||
******
|
|
||||||
|
|
||||||
The driver takes a parameter called ``extraCordappPackagesToScan`` which is a list of packages to use as CorDapps.
|
|
||||||
|
|
||||||
.. sourcecode:: java
|
|
||||||
|
|
||||||
driver(new DriverParameters().setExtraCordappPackagesToScan(Arrays.asList("com.domain.cordapp"))) ...
|
|
||||||
|
|
||||||
Full Nodes
|
|
||||||
**********
|
|
||||||
|
|
||||||
When testing against full nodes simply place your CorDapp into the cordapps directory of the node.
|
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
---------
|
---------
|
||||||
If an attachment constraint cannot be resolved, a ``MissingContractAttachments`` exception is thrown. There are two
|
If an attachment constraint cannot be resolved, a ``MissingContractAttachments`` exception is thrown. There are two
|
||||||
|
@ -22,108 +22,20 @@ A ``MockNetwork`` is created as follows:
|
|||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
.. sourcecode:: kotlin
|
.. literalinclude:: ../../docs/source/example-code/src/main/kotlin/net/corda/docs/kotlin/MockNetworkTestsTutorial.kt
|
||||||
|
:language: kotlin
|
||||||
|
:start-after: DOCSTART 1
|
||||||
|
:end-before: DOCEND 1
|
||||||
|
|
||||||
class FlowTests {
|
.. literalinclude:: ../../docs/source/example-code/src/main/java/net/corda/docs/java/MockNetworkTestsTutorial.java
|
||||||
private lateinit var mockNet: MockNetwork
|
:language: java
|
||||||
|
:start-after: DOCSTART 1
|
||||||
|
:end-before: DOCEND 1
|
||||||
|
|
||||||
@Before
|
The ``MockNetwork`` requires at a minimum a list of CorDapps to be installed on each ``StartedMockNode``. The CorDapps are looked up on the
|
||||||
fun setup() {
|
classpath by package name, using ``TestCordapp.findCordapp``.
|
||||||
network = MockNetwork(listOf("my.cordapp.package", "my.other.cordapp.package"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
``MockNetworkParameters`` provides other properties for the network which can be tweaked. They default to sensible values if not specified.
|
||||||
.. sourcecode:: java
|
|
||||||
|
|
||||||
public class IOUFlowTests {
|
|
||||||
private MockNetwork network;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
network = new MockNetwork(ImmutableList.of("my.cordapp.package", "my.other.cordapp.package"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
The ``MockNetwork`` requires at a minimum a list of packages. Each package is packaged into a CorDapp JAR and installed
|
|
||||||
as a CorDapp on each ``StartedMockNode``.
|
|
||||||
|
|
||||||
Configuring the ``MockNetwork``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``MockNetwork`` is configured automatically. You can tweak its configuration using a ``MockNetworkParameters``
|
|
||||||
object, or by using named parameters in Kotlin:
|
|
||||||
|
|
||||||
.. container:: codeset
|
|
||||||
|
|
||||||
.. sourcecode:: kotlin
|
|
||||||
|
|
||||||
val network = MockNetwork(
|
|
||||||
// A list of packages to scan. Any contracts, flows and Corda services within these
|
|
||||||
// packages will be automatically available to any nodes within the mock network
|
|
||||||
cordappPackages = listOf("my.cordapp.package", "my.other.cordapp.package"),
|
|
||||||
// If true then each node will be run in its own thread. This can result in race conditions in your
|
|
||||||
// code if not carefully written, but is more realistic and may help if you have flows in your app that
|
|
||||||
// do long blocking operations.
|
|
||||||
threadPerNode = false,
|
|
||||||
// The notaries to use on the mock network. By default you get one mock notary and that is usually
|
|
||||||
// sufficient.
|
|
||||||
notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)),
|
|
||||||
// If true then messages will not be routed from sender to receiver until you use the
|
|
||||||
// [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code that can
|
|
||||||
// examine the state of the mock network before and after a message is sent, without races and without
|
|
||||||
// the receiving node immediately sending a response.
|
|
||||||
networkSendManuallyPumped = false,
|
|
||||||
// How traffic is allocated in the case where multiple nodes share a single identity, which happens for
|
|
||||||
// notaries in a cluster. You don't normally ever need to change this: it is mostly useful for testing
|
|
||||||
// notary implementations.
|
|
||||||
servicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random())
|
|
||||||
|
|
||||||
val network2 = MockNetwork(
|
|
||||||
// A list of packages to scan. Any contracts, flows and Corda services within these
|
|
||||||
// packages will be automatically available to any nodes within the mock network
|
|
||||||
listOf("my.cordapp.package", "my.other.cordapp.package"), MockNetworkParameters(
|
|
||||||
// If true then each node will be run in its own thread. This can result in race conditions in your
|
|
||||||
// code if not carefully written, but is more realistic and may help if you have flows in your app that
|
|
||||||
// do long blocking operations.
|
|
||||||
threadPerNode = false,
|
|
||||||
// The notaries to use on the mock network. By default you get one mock notary and that is usually
|
|
||||||
// sufficient.
|
|
||||||
notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)),
|
|
||||||
// If true then messages will not be routed from sender to receiver until you use the
|
|
||||||
// [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code that can
|
|
||||||
// examine the state of the mock network before and after a message is sent, without races and without
|
|
||||||
// the receiving node immediately sending a response.
|
|
||||||
networkSendManuallyPumped = false,
|
|
||||||
// How traffic is allocated in the case where multiple nodes share a single identity, which happens for
|
|
||||||
// notaries in a cluster. You don't normally ever need to change this: it is mostly useful for testing
|
|
||||||
// notary implementations.
|
|
||||||
servicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random())
|
|
||||||
)
|
|
||||||
|
|
||||||
.. sourcecode:: java
|
|
||||||
|
|
||||||
MockNetwork network = MockNetwork(
|
|
||||||
// A list of packages to scan. Any contracts, flows and Corda services within these
|
|
||||||
// packages will be automatically available to any nodes within the mock network
|
|
||||||
ImmutableList.of("my.cordapp.package", "my.other.cordapp.package"),
|
|
||||||
new MockNetworkParameters()
|
|
||||||
// If true then each node will be run in its own thread. This can result in race conditions in
|
|
||||||
// your code if not carefully written, but is more realistic and may help if you have flows in
|
|
||||||
// your app that do long blocking operations.
|
|
||||||
.setThreadPerNode(false)
|
|
||||||
// The notaries to use on the mock network. By default you get one mock notary and that is
|
|
||||||
// usually sufficient.
|
|
||||||
.setNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(DUMMY_NOTARY_NAME)))
|
|
||||||
// If true then messages will not be routed from sender to receiver until you use the
|
|
||||||
// [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code
|
|
||||||
// that can examine the state of the mock network before and after a message is sent, without
|
|
||||||
// races and without the receiving node immediately sending a response.
|
|
||||||
.setNetworkSendManuallyPumped(false)
|
|
||||||
// How traffic is allocated in the case where multiple nodes share a single identity, which
|
|
||||||
// happens for notaries in a cluster. You don't normally ever need to change this: it is mostly
|
|
||||||
// useful for testing notary implementations.
|
|
||||||
.setServicePeerAllocationStrategy(new InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random()));
|
|
||||||
|
|
||||||
Adding nodes to the network
|
Adding nodes to the network
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -132,73 +44,21 @@ Nodes are created on the ``MockNetwork`` using:
|
|||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
.. sourcecode:: kotlin
|
.. literalinclude:: ../../docs/source/example-code/src/main/kotlin/net/corda/docs/kotlin/MockNetworkTestsTutorial.kt
|
||||||
|
:language: kotlin
|
||||||
|
:start-after: DOCSTART 2
|
||||||
|
:end-before: DOCEND 2
|
||||||
|
|
||||||
class FlowTests {
|
.. literalinclude:: ../../docs/source/example-code/src/main/java/net/corda/docs/java/MockNetworkTestsTutorial.java
|
||||||
private lateinit var mockNet: MockNetwork
|
:language: java
|
||||||
lateinit var nodeA: StartedMockNode
|
:start-after: DOCSTART 2
|
||||||
lateinit var nodeB: StartedMockNode
|
:end-before: DOCEND 2
|
||||||
|
|
||||||
@Before
|
Nodes added using ``createNode`` are provided a default set of node parameters. However, it is also possible to
|
||||||
fun setup() {
|
provide different parameters to each node using ``MockNodeParameters``. Of particular interest are ``configOverrides`` which allow you to
|
||||||
network = MockNetwork(listOf("my.cordapp.package", "my.other.cordapp.package"))
|
override some of the default node configuration options. Please refer to the ``MockNodeConfigOverrides`` class for details what can currently
|
||||||
nodeA = network.createPartyNode()
|
be overridden. Also, the ``additionalCordapps`` parameter allows you to add extra CorDapps to a specific node. This is useful when you wish
|
||||||
// We can optionally give the node a name.
|
for all nodes to load a common CorDapp but for a subset of nodes to load CorDapps specific to their role in the network.
|
||||||
nodeB = network.createPartyNode(CordaX500Name("Bank B", "London", "GB"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.. sourcecode:: java
|
|
||||||
|
|
||||||
public class IOUFlowTests {
|
|
||||||
private MockNetwork network;
|
|
||||||
private StartedMockNode a;
|
|
||||||
private StartedMockNode b;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
network = new MockNetwork(ImmutableList.of("my.cordapp.package", "my.other.cordapp.package"));
|
|
||||||
nodeA = network.createPartyNode(null);
|
|
||||||
// We can optionally give the node a name.
|
|
||||||
nodeB = network.createPartyNode(new CordaX500Name("Bank B", "London", "GB"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Nodes added using ``createPartyNode`` are provided a default set of node parameters. However, it is also possible to
|
|
||||||
provide different parameters to each node using the following methods on ``MockNetwork``:
|
|
||||||
|
|
||||||
.. container:: codeset
|
|
||||||
|
|
||||||
.. sourcecode:: kotlin
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a started node with the given parameters.
|
|
||||||
*
|
|
||||||
* @param legalName The node's legal name.
|
|
||||||
* @param forcedID A unique identifier for the node.
|
|
||||||
* @param entropyRoot The initial entropy value to use when generating keys. Defaults to an (insecure) random value,
|
|
||||||
* but can be overridden to cause nodes to have stable or colliding identity/service keys.
|
|
||||||
* @param configOverrides Add/override the default configuration/behaviour of the node
|
|
||||||
* @param extraCordappPackages Extra CorDapp packages to add for this node.
|
|
||||||
*/
|
|
||||||
@JvmOverloads
|
|
||||||
fun createNode(legalName: CordaX500Name? = null,
|
|
||||||
forcedID: Int? = null,
|
|
||||||
entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
|
|
||||||
configOverrides: MockNodeConfigOverrides? = null,
|
|
||||||
extraCordappPackages: List<String> = emptyList()
|
|
||||||
): StartedMockNode
|
|
||||||
|
|
||||||
/** Create a started node with the given parameters. **/
|
|
||||||
fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedMockNode
|
|
||||||
|
|
||||||
As you can see above, parameters can be added individually or encapsulated within a ``MockNodeParameters`` object. Of
|
|
||||||
particular interest are ``configOverrides`` which allow you to override some of the default node
|
|
||||||
configuration options. Please refer to the ``MockNodeConfigOverrides`` class for details what can currently be overridden.
|
|
||||||
Also, the ``extraCordappPackages`` parameter allows you to add extra CorDapps to a
|
|
||||||
specific node. This is useful when you wish for all nodes to load a common CorDapp but for a subset of nodes to load
|
|
||||||
CorDapps specific to their role in the network.
|
|
||||||
|
|
||||||
Running the network
|
Running the network
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package net.corda.docs.java;
|
||||||
|
|
||||||
|
// DOCSTART 1
|
||||||
|
import net.corda.core.identity.CordaX500Name;
|
||||||
|
import net.corda.testing.node.MockNetwork;
|
||||||
|
import net.corda.testing.node.MockNetworkParameters;
|
||||||
|
import net.corda.testing.node.StartedMockNode;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
import static net.corda.testing.node.TestCordapp.findCordapp;
|
||||||
|
|
||||||
|
public class MockNetworkTestsTutorial {
|
||||||
|
|
||||||
|
private final MockNetwork mockNet = new MockNetwork(new MockNetworkParameters(singletonList(findCordapp("com.mycordapp.package"))));
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanUp() {
|
||||||
|
mockNet.stopNodes();
|
||||||
|
}
|
||||||
|
// DOCEND 1
|
||||||
|
|
||||||
|
// DOCSTART 2
|
||||||
|
private StartedMockNode nodeA;
|
||||||
|
private StartedMockNode nodeB;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
nodeA = mockNet.createNode();
|
||||||
|
// We can optionally give the node a name.
|
||||||
|
nodeB = mockNet.createNode(new CordaX500Name("Bank B", "London", "GB"));
|
||||||
|
}
|
||||||
|
// DOCEND 2
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package net.corda.docs.kotlin
|
||||||
|
|
||||||
|
// DOCSTART 1
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.testing.node.MockNetwork
|
||||||
|
import net.corda.testing.node.MockNetworkParameters
|
||||||
|
import net.corda.testing.node.StartedMockNode
|
||||||
|
import net.corda.testing.node.TestCordapp.Companion.findCordapp
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
|
||||||
|
class MockNetworkTestsTutorial {
|
||||||
|
|
||||||
|
private val mockNet = MockNetwork(MockNetworkParameters(listOf(findCordapp("com.mycordapp.package"))))
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun cleanUp() {
|
||||||
|
mockNet.stopNodes()
|
||||||
|
}
|
||||||
|
// DOCEND 1
|
||||||
|
|
||||||
|
// DOCSTART 2
|
||||||
|
private lateinit var nodeA: StartedMockNode
|
||||||
|
private lateinit var nodeB: StartedMockNode
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
nodeA = mockNet.createNode()
|
||||||
|
// We can optionally give the node a name.
|
||||||
|
nodeB = mockNet.createNode(CordaX500Name("Bank B", "London", "GB"))
|
||||||
|
}
|
||||||
|
// DOCEND 2
|
||||||
|
}
|
@ -269,19 +269,10 @@ Here's an example of it in action from ``FixingFlow.Fixer``.
|
|||||||
Testing
|
Testing
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The ``MockNetwork`` allows the creation of ``MockNode`` instances, which are simplified nodes which can be used for
|
The ``MockNetwork`` allows the creation of ``MockNode`` instances, which are simplified nodes which can be used for testing (see :doc:`api-testing`).
|
||||||
testing (see :doc:`api-testing`). When creating the ``MockNetwork`` you supply a list of packages to scan for CorDapps.
|
When creating the ``MockNetwork`` you supply a list of ``TestCordapp`` objects which point to CorDapps on
|
||||||
Make sure the packages you provide include your oracle service, and it automatically be installed in the test nodes.
|
the classpath. These CorDapps will be installed on each node on the network. Make sure the packages you provide reference to the CorDapp
|
||||||
Then you can create an oracle node on the ``MockNetwork`` and insert any initialisation logic you want to use. In this
|
containing your oracle service.
|
||||||
case, our ``Oracle`` service is in the ``net.corda.irs.api`` package, so the following test setup will install
|
|
||||||
the service in each node. Then an oracle node with an oracle service which is initialised with some data is created on
|
|
||||||
the mock network:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../samples/irs-demo/cordapp/src/test/kotlin/net/corda/irs/api/OracleNodeTearOffTests.kt
|
|
||||||
:language: kotlin
|
|
||||||
:start-after: DOCSTART 1
|
|
||||||
:end-before: DOCEND 1
|
|
||||||
:dedent: 4
|
|
||||||
|
|
||||||
You can then write tests on your mock network to verify the nodes interact with your Oracle correctly.
|
You can then write tests on your mock network to verify the nodes interact with your Oracle correctly.
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import net.corda.core.identity.Party
|
|||||||
import net.corda.core.utilities.unwrap
|
import net.corda.core.utilities.unwrap
|
||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
|
import net.corda.testing.node.MockNetworkParameters
|
||||||
import net.corda.testing.node.MockNodeParameters
|
import net.corda.testing.node.MockNodeParameters
|
||||||
import net.corda.testing.node.StartedMockNode
|
import net.corda.testing.node.StartedMockNode
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -26,7 +27,7 @@ class FlowRegistrationTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
// no cordapps scanned so it can be tested in isolation
|
// no cordapps scanned so it can be tested in isolation
|
||||||
mockNetwork = MockNetwork()
|
mockNetwork = MockNetwork(MockNetworkParameters())
|
||||||
initiator = mockNetwork.createNode(MockNodeParameters(legalName = CordaX500Name("initiator", "Reading", "GB")))
|
initiator = mockNetwork.createNode(MockNodeParameters(legalName = CordaX500Name("initiator", "Reading", "GB")))
|
||||||
responder = mockNetwork.createNode(MockNodeParameters(legalName = CordaX500Name("responder", "Reading", "GB")))
|
responder = mockNetwork.createNode(MockNodeParameters(legalName = CordaX500Name("responder", "Reading", "GB")))
|
||||||
mockNetwork.runNetwork()
|
mockNetwork.runNetwork()
|
||||||
|
@ -68,7 +68,7 @@ class OracleNodeTearOffTests {
|
|||||||
mockNet.stopNodes()
|
mockNet.stopNodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOCSTART 2
|
// DOCSTART 1
|
||||||
@Test
|
@Test
|
||||||
fun `verify that the oracle signs the transaction if the interest rate within allowed limit`() {
|
fun `verify that the oracle signs the transaction if the interest rate within allowed limit`() {
|
||||||
// Create a partial transaction
|
// Create a partial transaction
|
||||||
@ -93,7 +93,7 @@ class OracleNodeTearOffTests {
|
|||||||
// Check that the transaction has been signed by the oracle
|
// Check that the transaction has been signed by the oracle
|
||||||
assertContains(fix.signers, oracle.owningKey)
|
assertContains(fix.signers, oracle.owningKey)
|
||||||
}
|
}
|
||||||
// DOCEND 2
|
// DOCEND 1
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `verify that the oracle rejects the transaction if the interest rate is outside the allowed limit`() {
|
fun `verify that the oracle rejects the transaction if the interest rate is outside the allowed limit`() {
|
||||||
|
@ -10,7 +10,7 @@ class MockNetworkIntegrationTests {
|
|||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
MockNetwork().run {
|
MockNetwork(MockNetworkParameters()).run {
|
||||||
repeat(2) { createNode() }
|
repeat(2) { createNode() }
|
||||||
runNetwork()
|
runNetwork()
|
||||||
stopNodes()
|
stopNodes()
|
||||||
|
@ -248,7 +248,9 @@ data class DriverParameters(
|
|||||||
val notaryCustomOverrides: Map<String, Any?> = emptyMap(),
|
val notaryCustomOverrides: Map<String, Any?> = emptyMap(),
|
||||||
val inMemoryDB: Boolean = true,
|
val inMemoryDB: Boolean = true,
|
||||||
val cordappsForAllNodes: Collection<TestCordapp>? = null
|
val cordappsForAllNodes: Collection<TestCordapp>? = null
|
||||||
) {
|
) {
|
||||||
|
constructor(cordappsForAllNodes: Collection<TestCordapp>) : this(isDebug = false, cordappsForAllNodes = cordappsForAllNodes)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
isDebug: Boolean = false,
|
isDebug: Boolean = false,
|
||||||
driverDirectory: Path = Paths.get("build") / "node-driver" / getTimestampAsDirectoryName(),
|
driverDirectory: Path = Paths.get("build") / "node-driver" / getTimestampAsDirectoryName(),
|
||||||
@ -313,38 +315,6 @@ data class DriverParameters(
|
|||||||
cordappsForAllNodes = null
|
cordappsForAllNodes = null
|
||||||
)
|
)
|
||||||
|
|
||||||
constructor(
|
|
||||||
isDebug: Boolean,
|
|
||||||
driverDirectory: Path,
|
|
||||||
portAllocation: PortAllocation,
|
|
||||||
debugPortAllocation: PortAllocation,
|
|
||||||
systemProperties: Map<String, String>,
|
|
||||||
useTestClock: Boolean,
|
|
||||||
startNodesInProcess: Boolean,
|
|
||||||
waitForAllNodesToFinish: Boolean,
|
|
||||||
notarySpecs: List<NotarySpec>,
|
|
||||||
extraCordappPackagesToScan: List<String>,
|
|
||||||
jmxPolicy: JmxPolicy,
|
|
||||||
networkParameters: NetworkParameters,
|
|
||||||
cordappsForAllNodes: Collection<TestCordapp>? = null
|
|
||||||
) : this(
|
|
||||||
isDebug,
|
|
||||||
driverDirectory,
|
|
||||||
portAllocation,
|
|
||||||
debugPortAllocation,
|
|
||||||
systemProperties,
|
|
||||||
useTestClock,
|
|
||||||
startNodesInProcess,
|
|
||||||
waitForAllNodesToFinish,
|
|
||||||
notarySpecs,
|
|
||||||
extraCordappPackagesToScan,
|
|
||||||
jmxPolicy,
|
|
||||||
networkParameters,
|
|
||||||
emptyMap(),
|
|
||||||
true,
|
|
||||||
cordappsForAllNodes
|
|
||||||
)
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
isDebug: Boolean,
|
isDebug: Boolean,
|
||||||
driverDirectory: Path,
|
driverDirectory: Path,
|
||||||
@ -377,39 +347,6 @@ data class DriverParameters(
|
|||||||
cordappsForAllNodes = null
|
cordappsForAllNodes = null
|
||||||
)
|
)
|
||||||
|
|
||||||
constructor(
|
|
||||||
isDebug: Boolean,
|
|
||||||
driverDirectory: Path,
|
|
||||||
portAllocation: PortAllocation,
|
|
||||||
debugPortAllocation: PortAllocation,
|
|
||||||
systemProperties: Map<String, String>,
|
|
||||||
useTestClock: Boolean,
|
|
||||||
startNodesInProcess: Boolean,
|
|
||||||
waitForAllNodesToFinish: Boolean,
|
|
||||||
notarySpecs: List<NotarySpec>,
|
|
||||||
extraCordappPackagesToScan: List<String>,
|
|
||||||
jmxPolicy: JmxPolicy,
|
|
||||||
networkParameters: NetworkParameters,
|
|
||||||
inMemoryDB: Boolean,
|
|
||||||
cordappsForAllNodes: Set<TestCordapp>? = null
|
|
||||||
) : this(
|
|
||||||
isDebug,
|
|
||||||
driverDirectory,
|
|
||||||
portAllocation,
|
|
||||||
debugPortAllocation,
|
|
||||||
systemProperties,
|
|
||||||
useTestClock,
|
|
||||||
startNodesInProcess,
|
|
||||||
waitForAllNodesToFinish,
|
|
||||||
notarySpecs,
|
|
||||||
extraCordappPackagesToScan,
|
|
||||||
jmxPolicy,
|
|
||||||
networkParameters,
|
|
||||||
emptyMap(),
|
|
||||||
inMemoryDB,
|
|
||||||
cordappsForAllNodes
|
|
||||||
)
|
|
||||||
|
|
||||||
fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug)
|
fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug)
|
||||||
fun withDriverDirectory(driverDirectory: Path): DriverParameters = copy(driverDirectory = driverDirectory)
|
fun withDriverDirectory(driverDirectory: Path): DriverParameters = copy(driverDirectory = driverDirectory)
|
||||||
fun withPortAllocation(portAllocation: PortAllocation): DriverParameters = copy(portAllocation = portAllocation)
|
fun withPortAllocation(portAllocation: PortAllocation): DriverParameters = copy(portAllocation = portAllocation)
|
||||||
@ -419,6 +356,8 @@ data class DriverParameters(
|
|||||||
fun withStartNodesInProcess(startNodesInProcess: Boolean): DriverParameters = copy(startNodesInProcess = startNodesInProcess)
|
fun withStartNodesInProcess(startNodesInProcess: Boolean): DriverParameters = copy(startNodesInProcess = startNodesInProcess)
|
||||||
fun withWaitForAllNodesToFinish(waitForAllNodesToFinish: Boolean): DriverParameters = copy(waitForAllNodesToFinish = waitForAllNodesToFinish)
|
fun withWaitForAllNodesToFinish(waitForAllNodesToFinish: Boolean): DriverParameters = copy(waitForAllNodesToFinish = waitForAllNodesToFinish)
|
||||||
fun withNotarySpecs(notarySpecs: List<NotarySpec>): DriverParameters = copy(notarySpecs = notarySpecs)
|
fun withNotarySpecs(notarySpecs: List<NotarySpec>): DriverParameters = copy(notarySpecs = notarySpecs)
|
||||||
|
@Deprecated("extraCordappPackagesToScan does not preserve the original CorDapp's versioning and metadata, which may lead to " +
|
||||||
|
"misleading results in tests. Use withCordappsForAllNodes instead.")
|
||||||
fun withExtraCordappPackagesToScan(extraCordappPackagesToScan: List<String>): DriverParameters = copy(extraCordappPackagesToScan = extraCordappPackagesToScan)
|
fun withExtraCordappPackagesToScan(extraCordappPackagesToScan: List<String>): DriverParameters = copy(extraCordappPackagesToScan = extraCordappPackagesToScan)
|
||||||
fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy)
|
fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy)
|
||||||
fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters)
|
fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters)
|
||||||
|
@ -61,8 +61,7 @@ data class MockNodeParameters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable builder for configuring a [MockNetwork]. Kotlin users can also use named parameters to the constructor
|
* Immutable builder for configuring a [MockNetwork].
|
||||||
* of [MockNetwork], which is more convenient.
|
|
||||||
*
|
*
|
||||||
* @property networkSendManuallyPumped If false then messages will not be routed from sender to receiver until you use
|
* @property networkSendManuallyPumped If false then messages will not be routed from sender to receiver until you use
|
||||||
* the [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code that can examine the
|
* the [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code that can examine the
|
||||||
@ -95,6 +94,8 @@ data class MockNetworkParameters(
|
|||||||
networkParameters: NetworkParameters
|
networkParameters: NetworkParameters
|
||||||
) : this(networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, notarySpecs, networkParameters, emptyList())
|
) : this(networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, notarySpecs, networkParameters, emptyList())
|
||||||
|
|
||||||
|
constructor(cordappsForAllNodes: Collection<TestCordapp>) : this(threadPerNode = false, cordappsForAllNodes = cordappsForAllNodes)
|
||||||
|
|
||||||
fun withNetworkParameters(networkParameters: NetworkParameters): MockNetworkParameters = copy(networkParameters = networkParameters)
|
fun withNetworkParameters(networkParameters: NetworkParameters): MockNetworkParameters = copy(networkParameters = networkParameters)
|
||||||
fun withNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean): MockNetworkParameters = copy(networkSendManuallyPumped = networkSendManuallyPumped)
|
fun withNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean): MockNetworkParameters = copy(networkSendManuallyPumped = networkSendManuallyPumped)
|
||||||
fun withThreadPerNode(threadPerNode: Boolean): MockNetworkParameters = copy(threadPerNode = threadPerNode)
|
fun withThreadPerNode(threadPerNode: Boolean): MockNetworkParameters = copy(threadPerNode = threadPerNode)
|
||||||
@ -108,7 +109,8 @@ data class MockNetworkParameters(
|
|||||||
threadPerNode: Boolean,
|
threadPerNode: Boolean,
|
||||||
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy,
|
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy,
|
||||||
notarySpecs: List<MockNetworkNotarySpec>,
|
notarySpecs: List<MockNetworkNotarySpec>,
|
||||||
networkParameters: NetworkParameters): MockNetworkParameters {
|
networkParameters: NetworkParameters
|
||||||
|
): MockNetworkParameters {
|
||||||
return MockNetworkParameters(networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, notarySpecs, networkParameters, emptyList())
|
return MockNetworkParameters(networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, notarySpecs, networkParameters, emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,9 +245,9 @@ class StartedMockNode private constructor(private val node: TestStartedNode) {
|
|||||||
* By default a single notary node is automatically started, which forms part of the network parameters for all the nodes.
|
* By default a single notary node is automatically started, which forms part of the network parameters for all the nodes.
|
||||||
* This node is available by calling [defaultNotaryNode].
|
* This node is available by calling [defaultNotaryNode].
|
||||||
*
|
*
|
||||||
|
* @property defaultParameters The default parameters for the network. If any of the remaining constructor parameters are specified then
|
||||||
|
* their values are taken instead of the corresponding value in [defaultParameters].
|
||||||
* @property cordappPackages A [List] of cordapp packages to scan for any cordapp code, e.g. contract verification code, flows and services.
|
* @property cordappPackages A [List] of cordapp packages to scan for any cordapp code, e.g. contract verification code, flows and services.
|
||||||
* @property defaultParameters A [MockNetworkParameters] object which contains the same parameters as the constructor, provided
|
|
||||||
* as a convenience for Java users.
|
|
||||||
* @property networkSendManuallyPumped If false then messages will not be routed from sender to receiver until you use
|
* @property networkSendManuallyPumped If false then messages will not be routed from sender to receiver until you use
|
||||||
* the [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code that can examine the
|
* the [MockNetwork.runNetwork] method. This is useful for writing single-threaded unit test code that can examine the
|
||||||
* state of the mock network before and after a message is sent, without races and without the receiving node immediately
|
* state of the mock network before and after a message is sent, without races and without the receiving node immediately
|
||||||
@ -279,8 +281,7 @@ open class MockNetwork(
|
|||||||
cordappPackages, defaultParameters = parameters
|
cordappPackages, defaultParameters = parameters
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmOverloads
|
constructor(parameters: MockNetworkParameters) : this(emptyList(), defaultParameters = parameters)
|
||||||
constructor(parameters: MockNetworkParameters = MockNetworkParameters()) : this(emptyList(), parameters)
|
|
||||||
|
|
||||||
private val internalMockNetwork = InternalMockNetwork(
|
private val internalMockNetwork = InternalMockNetwork(
|
||||||
cordappPackages,
|
cordappPackages,
|
||||||
@ -317,7 +318,7 @@ open class MockNetwork(
|
|||||||
fun createPartyNode(legalName: CordaX500Name? = null): StartedMockNode = StartedMockNode.create(internalMockNetwork.createPartyNode(legalName))
|
fun createPartyNode(legalName: CordaX500Name? = null): StartedMockNode = StartedMockNode.create(internalMockNetwork.createPartyNode(legalName))
|
||||||
|
|
||||||
/** Create a started node with the given parameters. **/
|
/** Create a started node with the given parameters. **/
|
||||||
fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedMockNode {
|
fun createNode(parameters: MockNodeParameters): StartedMockNode {
|
||||||
return StartedMockNode.create(internalMockNetwork.createNode(InternalMockNodeParameters(parameters)))
|
return StartedMockNode.create(internalMockNetwork.createNode(InternalMockNodeParameters(parameters)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import net.corda.testing.driver.NodeParameters
|
|||||||
import net.corda.testing.node.internal.TestCordappImpl
|
import net.corda.testing.node.internal.TestCordappImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates a CorDapp that exists on the current classpath, which can be pulled in for testing. Use [TestCordapp.Factory.findCordapp]
|
* Encapsulates a CorDapp that exists on the current classpath, which can be pulled in for testing. Use [TestCordapp.findCordapp]
|
||||||
* to locate an existing CorDapp.
|
* to locate an existing CorDapp.
|
||||||
*
|
*
|
||||||
* @see DriverParameters.cordappsForAllNodes
|
* @see DriverParameters.cordappsForAllNodes
|
||||||
@ -15,27 +15,25 @@ import net.corda.testing.node.internal.TestCordappImpl
|
|||||||
* @see MockNodeParameters.additionalCordapps
|
* @see MockNodeParameters.additionalCordapps
|
||||||
*/
|
*/
|
||||||
@DoNotImplement
|
@DoNotImplement
|
||||||
interface TestCordapp {
|
abstract class TestCordapp {
|
||||||
/** The package used to find the CorDapp. This may not be the root package of the CorDapp. */
|
/** The package used to find the CorDapp. This may not be the root package of the CorDapp. */
|
||||||
val scanPackage: String
|
abstract val scanPackage: String
|
||||||
|
|
||||||
/** Returns the config for on this CorDapp, defaults to empty if not specified. */
|
/** Returns the config for on this CorDapp, defaults to empty if not specified. */
|
||||||
val config: Map<String, Any>
|
abstract val config: Map<String, Any>
|
||||||
|
|
||||||
/** Returns a copy of this [TestCordapp] but with the specified CorDapp config. */
|
/** Returns a copy of this [TestCordapp] but with the specified CorDapp config. */
|
||||||
fun withConfig(config: Map<String, Any>): TestCordapp
|
abstract fun withConfig(config: Map<String, Any>): TestCordapp
|
||||||
|
|
||||||
class Factory {
|
companion object {
|
||||||
companion object {
|
/**
|
||||||
/**
|
* Scans the current classpath to find the CorDapp that contains the given package. All the CorDapp's metdata present in its
|
||||||
* Scans the current classpath to find the CorDapp that contains the given package. All the CorDapp's metdata present in its
|
* MANIFEST are inherited. If more than one location containing the package is found then an exception is thrown. An exception
|
||||||
* MANIFEST are inherited. If more than one location containing the package is found then an exception is thrown. An exception
|
* is also thrown if no CorDapp is found.
|
||||||
* is also thrown if no CorDapp is found.
|
*
|
||||||
*
|
* @param scanPackage The package name used to find the CorDapp. This does not need to be the root package of the CorDapp.
|
||||||
* @param scanPackage The package name used to find the CorDapp. This does not need to be the root package.
|
*/
|
||||||
*/
|
@JvmStatic
|
||||||
@JvmStatic
|
fun findCordapp(scanPackage: String): TestCordapp = TestCordappImpl(scanPackage = scanPackage, config = emptyMap())
|
||||||
fun findCordapp(scanPackage: String): TestCordapp = TestCordappImpl(scanPackage = scanPackage, config = emptyMap())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ data class CustomCordapp(
|
|||||||
val classes: Set<Class<*>> = emptySet(),
|
val classes: Set<Class<*>> = emptySet(),
|
||||||
val signingInfo: SigningInfo? = null,
|
val signingInfo: SigningInfo? = null,
|
||||||
override val config: Map<String, Any> = emptyMap()
|
override val config: Map<String, Any> = emptyMap()
|
||||||
) : TestCordappInternal {
|
) : TestCordappInternal() {
|
||||||
init {
|
init {
|
||||||
require(packages.isNotEmpty() || classes.isNotEmpty()) { "At least one package or class must be specified" }
|
require(packages.isNotEmpty() || classes.isNotEmpty()) { "At least one package or class must be specified" }
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,12 @@ import kotlin.streams.toList
|
|||||||
/**
|
/**
|
||||||
* Implementation of the public [TestCordapp] API.
|
* Implementation of the public [TestCordapp] API.
|
||||||
*
|
*
|
||||||
* As described in [TestCordapp.Factory.findCordapp], this represents a single CorDapp jar on the current classpath. The [scanPackage] may
|
* As described in [TestCordapp.findCordapp], this represents a single CorDapp jar on the current classpath. The [scanPackage] may
|
||||||
* be for an external dependency to the project that's using this API, in which case that dependency jar is referenced as is. On the other hand,
|
* be for an external dependency to the project that's using this API, in which case that dependency jar is referenced as is. On the other hand,
|
||||||
* the [scanPackage] may reference a gradle CorDapp project on the local system. In this scenerio the project's "jar" task is executed to
|
* the [scanPackage] may reference a gradle CorDapp project on the local system. In this scenerio the project's "jar" task is executed to
|
||||||
* build the CorDapp jar. This allows us to inherit the CorDapp's MANIFEST information without having to do any extra processing.
|
* build the CorDapp jar. This allows us to inherit the CorDapp's MANIFEST information without having to do any extra processing.
|
||||||
*/
|
*/
|
||||||
data class TestCordappImpl(override val scanPackage: String, override val config: Map<String, Any>) : TestCordappInternal {
|
data class TestCordappImpl(override val scanPackage: String, override val config: Map<String, Any>) : TestCordappInternal() {
|
||||||
override fun withConfig(config: Map<String, Any>): TestCordappImpl = copy(config = config)
|
override fun withConfig(config: Map<String, Any>): TestCordappImpl = copy(config = config)
|
||||||
|
|
||||||
override fun withOnlyJarContents(): TestCordappImpl = copy(config = emptyMap())
|
override fun withOnlyJarContents(): TestCordappImpl = copy(config = emptyMap())
|
||||||
@ -27,9 +27,11 @@ data class TestCordappImpl(override val scanPackage: String, override val config
|
|||||||
get() {
|
get() {
|
||||||
val jars = TestCordappImpl.findJars(scanPackage)
|
val jars = TestCordappImpl.findJars(scanPackage)
|
||||||
when (jars.size) {
|
when (jars.size) {
|
||||||
0 -> throw IllegalArgumentException("Package $scanPackage does not exist")
|
0 -> throw IllegalArgumentException("There are no CorDapps containing the package $scanPackage on the classpath. Make sure " +
|
||||||
|
"the package name is correct and that the CorDapp is added as a gradle dependency.")
|
||||||
1 -> return jars.first()
|
1 -> return jars.first()
|
||||||
else -> throw IllegalArgumentException("More than one jar found containing package $scanPackage: $jars")
|
else -> throw IllegalArgumentException("There is more than one CorDapp containing the package $scanPackage on the classpath " +
|
||||||
|
"$jars. Specify a package name which is unique to the CorDapp.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
|||||||
*
|
*
|
||||||
* @property jarFile The jar file this CorDapp represents. Different CorDapps may point to the same file.
|
* @property jarFile The jar file this CorDapp represents. Different CorDapps may point to the same file.
|
||||||
*/
|
*/
|
||||||
interface TestCordappInternal : TestCordapp {
|
abstract class TestCordappInternal : TestCordapp() {
|
||||||
val jarFile: Path
|
abstract val jarFile: Path
|
||||||
|
|
||||||
/** Return a copy of this TestCordappInternal but without any metadata, such as configs and signing information. */
|
/** Return a copy of this TestCordappInternal but without any metadata, such as configs and signing information. */
|
||||||
fun withOnlyJarContents(): TestCordappInternal
|
abstract fun withOnlyJarContents(): TestCordappInternal
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun installCordapps(baseDirectory: Path,
|
fun installCordapps(baseDirectory: Path,
|
||||||
|
@ -44,9 +44,9 @@ fun cordappForClasses(vararg classes: Class<*>): CustomCordapp = CustomCordapp(p
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the single CorDapp jar on the current classpath which contains the given package. This is a convenience method for
|
* Find the single CorDapp jar on the current classpath which contains the given package. This is a convenience method for
|
||||||
* [TestCordapp.Factory.findCordapp] but returns the internal [TestCordappImpl].
|
* [TestCordapp.findCordapp] but returns the internal [TestCordappImpl].
|
||||||
*/
|
*/
|
||||||
fun findCordapp(scanPackage: String): TestCordappImpl = TestCordapp.Factory.findCordapp(scanPackage) as TestCordappImpl
|
fun findCordapp(scanPackage: String): TestCordappImpl = TestCordapp.findCordapp(scanPackage) as TestCordappImpl
|
||||||
|
|
||||||
fun getCallerClass(directCallerClass: KClass<*>): Class<*>? {
|
fun getCallerClass(directCallerClass: KClass<*>): Class<*>? {
|
||||||
val stackTrace = Throwable().stackTrace
|
val stackTrace = Throwable().stackTrace
|
||||||
|
@ -16,7 +16,7 @@ class MockNetworkTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNetwork = MockNetwork()
|
mockNetwork = MockNetwork(MockNetworkParameters())
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
Loading…
x
Reference in New Issue
Block a user