Тестирование контракта в sandbox: unit-тесты

Напишешь unit-тесты на @ton/sandbox: деплой, сообщение, проверка транзакций и getters.

Sandbox

@ton/sandbox эмулирует блокчейн локально: деплой, сообщения, bounce и газ без testnet. В Blueprint тесты обычно на Jest + @ton/test-utils (матчер toHaveTransaction).


Тест Counter (Tact)

typescript
// @ton/sandbox ^0.27.0 · @ton/test-utils ^0.6.0 · @ton/core ^0.60.0
import { Blockchain, SandboxContract, TreasuryContract } from "@ton/sandbox";
import { toNano } from "@ton/core";
import { Counter } from "../build/Counter/tact_Counter";
import "@ton/test-utils";

describe("Counter", () => {
  let blockchain: Blockchain;
  let deployer: SandboxContract<TreasuryContract>;
  let counter: SandboxContract<Counter>;

  beforeEach(async () => {
    blockchain = await Blockchain.create();
    deployer = await blockchain.treasury("deployer");

    counter = blockchain.openContract(await Counter.fromInit(1n, 0n));

    const deployResult = await counter.send(
      deployer.getSender(),
      { value: toNano("0.05") },
      null,
    );

    expect(deployResult.transactions).toHaveTransaction({
      from: deployer.address,
      to: counter.address,
      deploy: true,
      success: true,
    });
  });

  it("increments via Add", async () => {
    const result = await counter.send(
      deployer.getSender(),
      { value: toNano("0.05") },
      { $$type: "Add", amount: 5n },
    );

    expect(result.transactions).toHaveTransaction({
      from: deployer.address,
      to: counter.address,
      success: true,
    });

    expect(await counter.getCounter()).toBe(5n);
  });

  it("rejects unknown sender for admin-only flow", async () => {
    // пример паттерна: отдельный treasury = «чужой» кошелёк
    const stranger = await blockchain.treasury("stranger");
    // добавь admin-only receiver в контракт и проверь success: false / exitCode
    expect(stranger.address.equals(deployer.address)).toBe(false);
  });
});
bash
npx blueprint test

Как это работает

  • Blockchain.create() — чистая сеть на каждый beforeEach (изолированные тесты).
  • treasury(name) — детерминированный кошелёк с балансом для оплаты сообщений.
  • $$type: "Add" — дискриминант Tact-сообщения в сгенерированной обёртке.
  • toHaveTransaction проверяет наличие tx с нужными from / to / success в цепочке.
  • Для bounce смотри отдельную транзакцию обратно на отправителя с inMessageBounced: true (через матчеры test-utils).

Частые ошибки

Не импортировал @ton/test-utilstoHaveTransaction не зарегистрируется.

Переиспользуешь один blockchain между тестами без reset → флаки из-за общего состояния.

Сверяешь number вместо bigintgetCounter() у Tact-обёрток часто возвращает bigint.


Что дальше

Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация