I have a function that takes a number of values, creates a new model, and then saves this in storage via a PersistentMap
.
I would like to test that the item is successfully saved in storage. This is how I'm going about it:
it("saves a new item to storage", () => {
VMContext.setCurrent_account_id("test_account_id");
contract.createMyPersistantMapItem(
"value 1",
"value 2",
"value 3"
);
expect(storage.hasKey("myPersistantMap::test_account_id")).toBeTruthy();
});
However the test fails with the following:
[Actual]: false
[Expected]: Truthy
[Stack]: RuntimeError: unreachable
at node_modules/@as-pect/assembly/assembly/internal/assert/assert (wasm-function[53]:0xd71)
at start:src/simple/__tests__/index.unit.spec~anonymous|0~anonymous|0~anonymous|0 (wasm-function[130]:0x2a84)
at node_modules/@as-pect/assembly/assembly/internal/call/__call (wasm-function[134]:0x2aac)
Am I going about this the wrong way?
Also I would like to test the values in the item are correct. In the todos example the created todo is returned from the function that creates it, and then this returned value is tested. Is this the best way of doing things to make testing easier?
EDIT
This is the createMyPersistantMapItem
function - edited a bit to make things clearer:
export function createMyPersistantMapItem(
blah1: string,
blah2: string,
blah3: string,
): void {
const accountId = context.sender;
assert(
!storage.hasKey("myPersistantMap::" + accountId),
"Item already exists"
);
const newPersistantMapItem = new PersistantMapItem(
blah1,
blah2,
blah3
);
myPersistantMap.set(accountId, newPersistantMapItem);
}
About the first question:
Does myPersistentMap
use the "myPersistantMap" prefix when initialized? Does PersistantMapItem
use the @nearBingden annotation on the class?
Also, in your test, I think you should use
VMContext.setSigner_account_id("test_account_id")
//instead of
VMContext.setCurrent_account_id("test_account_id")
Because you are using context.sender
when you call createMyPersistantMapItem
About the second question:
In the todos example the created todo is returned from the function that creates it, and then this returned value is tested. Is this the best way of doing things to make testing easier?
This question is primarily opinion based, so I can only answer for myself. Testing the returned value is completely fine. In a smart contract however, I would probably test if the value is actually stored on the contract. And I think they are doing that in the TODO example. They just use the ID of the generated TODO to do a query on the smart contract.
const a = Todo.insert("Drink water");
// They use the id of the todo (a) to check if it was actually stored, and is in fact the same object. I think this is fine.
expect(getById(a.id)).toStrictEqual(a);