如果依赖于某个先前状态,如何设置一个流的 UT?
How to setup the UT of one flow if depend on some previous state?
这是我的 demo source code,我已经创建了一个流程 "OrderPlaceFlow$Request" 用于下订单。
我想为这个流程写一个UT——PartyC和PartyB之间的订单交易,这个流程需要PartyA和PartyB的一些Token状态作为输入。
如何模拟或模拟 PartyB 拥有来自 PartyA 的 Token 状态?
按照@Joel的建议,我在PartyB中添加了之前的状态——token状态,但是仍然无法通过API查询到这个状态——getVaultService().queryBy.
下面是我的代码片段,或者从Github
获取完整的源代码
TokenState tokenState = new TokenState(
nodeA.getInfo().getLegalIdentities().get(0),
nodeB.getInfo().getLegalIdentities().get(0),
99);
TransactionBuilder transactionBuilder = new TransactionBuilder(network.getDefaultNotaryIdentity());
transactionBuilder.addOutputState(tokenState, TokenContract.ID, network.getDefaultNotaryIdentity());
CommandData commandData = new TokenContract.Issue();
transactionBuilder.addCommand(commandData, nodeA.getInfo().getLegalIdentities().get(0).getOwningKey());
nodeA.transaction(() -> {
try {
transactionBuilder.verify(nodeA.getServices());
} catch (TransactionVerificationException e) {
assertEquals(1, 1);
} catch (TransactionResolutionException e) {
assertEquals(2, 2);
} catch (AttachmentResolutionException e) {
assertEquals(3, 3);
}
return null;
});
SignedTransaction partSignedTransaction = nodeA.getServices().signInitialTransaction(transactionBuilder);
SignedTransaction signedTransaction = nodeB.getServices().addSignature(partSignedTransaction);
nodeA.getServices().recordTransactions(signedTransaction);
nodeB.getServices().recordTransactions(signedTransaction);
//find a Token State for order
QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED);
Vault.Page<TokenState> results = nodeB.getServices().getVaultService().queryBy(TokenState.class, criteria);
List<StateAndRef<TokenState>> tokenStates = results.getStates();
assertEquals(tokenStates.size(), 0);
谢谢乔尔。是的,我犯了一些愚蠢的错误,现在,我已经改正了。
但是,我的 UT 仍然失败,并出现这些错误:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [net.corda.node.services.vault.VaultSchemaV1$VaultStates#PersistentStateRef(txId=8F1461B9985457E9F5BC2AB72FD637621BB64649F58BE6D66114E48F24B6A555, index=0)]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:169)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
我研究了一下,保存98 TokenState时会报这个错。
但是我不明白为什么,因为99 TokenState在PartyA和PartyB保存了两次,但是PartyB不能保存98 TokenState。
希望有人能帮助我。
您上面的代码中似乎有错误。在最后一行,您断言:
assertEquals(tokenStates.size(), 0);
鉴于您期望节点库中的状态,它应该是:
assertEquals(tokenStates.size(), 1);
这是我的 demo source code,我已经创建了一个流程 "OrderPlaceFlow$Request" 用于下订单。
我想为这个流程写一个UT——PartyC和PartyB之间的订单交易,这个流程需要PartyA和PartyB的一些Token状态作为输入。
如何模拟或模拟 PartyB 拥有来自 PartyA 的 Token 状态?
按照@Joel的建议,我在PartyB中添加了之前的状态——token状态,但是仍然无法通过API查询到这个状态——getVaultService().queryBy.
下面是我的代码片段,或者从Github
获取完整的源代码 TokenState tokenState = new TokenState(
nodeA.getInfo().getLegalIdentities().get(0),
nodeB.getInfo().getLegalIdentities().get(0),
99);
TransactionBuilder transactionBuilder = new TransactionBuilder(network.getDefaultNotaryIdentity());
transactionBuilder.addOutputState(tokenState, TokenContract.ID, network.getDefaultNotaryIdentity());
CommandData commandData = new TokenContract.Issue();
transactionBuilder.addCommand(commandData, nodeA.getInfo().getLegalIdentities().get(0).getOwningKey());
nodeA.transaction(() -> {
try {
transactionBuilder.verify(nodeA.getServices());
} catch (TransactionVerificationException e) {
assertEquals(1, 1);
} catch (TransactionResolutionException e) {
assertEquals(2, 2);
} catch (AttachmentResolutionException e) {
assertEquals(3, 3);
}
return null;
});
SignedTransaction partSignedTransaction = nodeA.getServices().signInitialTransaction(transactionBuilder);
SignedTransaction signedTransaction = nodeB.getServices().addSignature(partSignedTransaction);
nodeA.getServices().recordTransactions(signedTransaction);
nodeB.getServices().recordTransactions(signedTransaction);
//find a Token State for order
QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED);
Vault.Page<TokenState> results = nodeB.getServices().getVaultService().queryBy(TokenState.class, criteria);
List<StateAndRef<TokenState>> tokenStates = results.getStates();
assertEquals(tokenStates.size(), 0);
谢谢乔尔。是的,我犯了一些愚蠢的错误,现在,我已经改正了。 但是,我的 UT 仍然失败,并出现这些错误:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [net.corda.node.services.vault.VaultSchemaV1$VaultStates#PersistentStateRef(txId=8F1461B9985457E9F5BC2AB72FD637621BB64649F58BE6D66114E48F24B6A555, index=0)]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:169)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
我研究了一下,保存98 TokenState时会报这个错。 但是我不明白为什么,因为99 TokenState在PartyA和PartyB保存了两次,但是PartyB不能保存98 TokenState。
希望有人能帮助我。
您上面的代码中似乎有错误。在最后一行,您断言:
assertEquals(tokenStates.size(), 0);
鉴于您期望节点库中的状态,它应该是:
assertEquals(tokenStates.size(), 1);