Unit testing a NEAR Smart Contract

Overview

Prerequisites

Objective

Import Boilerplate Source

Modify Smart Contract

import { storage, logging } from "near-sdk-as";

// --- contract code goes below

export function incrementCounter(value: i32): void {
  const newCounter = storage.getPrimitive<i32>("counter", 0) + value;
  storage.set<i32>("counter", newCounter);
  logging.log("Counter is now: " + newCounter.toString());
}

export function decrementCounter(value: i32): void {
  const newCounter = storage.getPrimitive<i32>("counter", 0) - value;
  storage.set<i32>("counter", newCounter);
  logging.log("Counter is now: " + newCounter.toString());
}

export function getCounter(): i32 {
  return storage.getPrimitive<i32>("counter", 0);
}

export function resetCounter(): void {
  storage.set<i32>("counter", 0);
  logging.log("Counter is reset!");
}

Modify Test

import {
    getCounter,
    resetCounter,
    incrementCounter,
    decrementCounter
} from '../index';

import { context, storage, VM } from 'near-sdk-as';

describe("Counter ", () => {
    it("should increment by one", () => {
        incrementCounter(1);
        expect(getCounter()).toBe(1, "counter should be one after a single increment.");
    });

    it("getCounter is the same as reading from storage", () => {
        expect(storage.getPrimitive<i32>("counter", 0)).toBe(getCounter(), "storage.getPrimitive<i32>(\"counter\", 0) = getCounter()");
    });

    it("should decrement by one", () => {
        incrementCounter(1);
        decrementCounter(1);
        expect(getCounter()).toBe(0, "counter should be zero after a single decrement.");
    });

    it("should be resetable", () => {
        incrementCounter(1);
        incrementCounter(1);
        resetCounter(); // reset to zero
        expect(getCounter()).toBe(0, "counter should be zero after it is reset."); 
    });
    
    it("should increment multiple times and decrement back to zero", () => {
        incrementCounter(1);
        expect(getCounter()).toBe(1, "0 + 1 = 1");
        incrementCounter(3);
        expect(getCounter()).toBe(4, "1 + 3 = 4");
        decrementCounter(4);
        expect(getCounter()).toBe(0, "4 - 4 = 0");
    });

    it("should be eve's account", () => {
        expect(context.contractName).toBe("eve");
    });
});

AssemblyScript Installation

Test Project

Modify Tests to Pass

import { ..., VMContext, ... } from 'near-sdk-as'
it("should be eve's account", () => {
    VMContext.setCurrent_account_id("eve");
    expect(context.contractName, "eve");
})

Import Bind Gen Decorator

Troubleshooting