-
Notifications
You must be signed in to change notification settings - Fork 14
TestWithJava
Thanks to the cool project https://github.com/adridadou/eth-contract-api it is possible to test the contract code via junit on a private blockchain, which is very nice as no blockchain sync is needed and the tests are fast and reproducible.
The code generator can produce the necessary interfaces for the contract and the corresponding junit tests.
To get all working together you will need a defined project setup.
In addition to the basic software (see) you need the maven plugin, as we will create a maven project.
- maven plugin for eclipse
At first create a maven project
create a simple project without archetypes.
and set the group and the artifact id
Now we need to add the dependencies for the project :
<dependencies>
<dependency>
<groupId>org.adridadou</groupId>
<artifactId>eth-contract-api</artifactId>
<version>0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
And this is all it's needed. We need junit and the eth-contract-api.
Now add your model and we just need to configure the code generator. As the junit test will compile the solidity code the contract code need to be on the classpath. So you need to point the generation for the contract to a directory which is on the classpath. As we want execute the junit tests the contract
So choose as generation directory for the contract code, for example, the 'src/test/resources' folder. Which is a nice place as it is on the classpath and also it is not a java code directory.
On the generate java page point the generation of the contract interfaces to a java folder, 'src/main/java' for example, as this is the place where the normal java code should go.
You could add a package prefix which is used as a suffix to the uml packages.
For the junit tests choose the 'src/test/java' folder as maven expect the junit tests there. Define the type mapping, when a type is missing just add it.
And you are ready to go.
For each contract a corresponding interface is created, when a function return more than one value the return value is stored in a generated dataholder named 'Return[op.name.toUpperFirst()/][op.operationReturnParameters()/]'. You will find more information in the wiki (https://github.com/adridadou/eth-contract-api/wiki/Complex-type-mapping). When a contract extends an other contract, the test will also extends the other contract test. There will be also a test function
For each contract a junit test is created named '[aClass.name/]Test', it contains a test method for each public function in the contract. For each package a TestSuite called 'All[p.name.toUpperFirst()/]TestSuite' is created containing all tests of this package.
The test contains a setup of the blockchain, and the deployment of the contract.
/**
* Setup up the blockchain.
*/
@BeforeClass
public static void setup() {
BlockchainProxy bcProxy = new BlockchainProxyTest();
sender = null;
ethereum = new EthereumFacade(bcProxy);
}
/**
* Read the contract from the file and deploys the contract code.
* @throws Exception
*/
@Before
public void prepareTest() throws Exception {
//Start of user code prepareTest
File contractSrc = new File(this.getClass().getResource("/mix/contract.sol").toURI());
contractSource = SoliditySource.from(contractSrc);
createFixture();
//End of user code
}
/**
* Create a new fixture by deploying the contract source.
* @throws Exception
*/
protected void createFixture() throws Exception {
//Start of user code createFixture
String _name = "_name";
String _url = "_url";
String _description = "_description";
CompletableFuture<EthAddress> address = ethereum.publishContract(contractSource, "ChecksumDatabase", sender
, _name, _url, _description);
fixtureAddress = address.get();
fixture = ethereum
.createContractProxy(contractSource, "ChecksumDatabase", address.get(), sender, ChecksumDatabase.class);
//End of user code
}
The 'setup()' method simply creates the infrastructure, this is done only once per test. The method 'prepareTest()' loads the contract code from the classpath and the method 'createFixture()' will deploy the contact and set the fixture field.
The naming schema for the test are test[op.name.toUpperFirst()/][op.operationParameters()/]. For example 'testAddEntry_string_string()'.