цепочка обещаний в файле test.js

  it("should throw an exception if you try to buy an article that does not exist", function() {
    return ChainList.deployed().then(function(instance) {
        chainListInstance = instance;
        return chainListInstance.sellArticle(articleName, articleDescription, web3.toWei(articlePrice, "ether"), {
          from: seller
        });
      }).then(function(receipt) {
        return chainListInstance.buyArticle(2, {
          from: buyer,
          value: web3.toWei(articlePrice, "ether")
        });
      }).then(assert.fail)
      .catch(function(error) {
        assert(error.message.indexOf('invalid opcode') >= 0, "error message must contain invalid opcode");
      }).then(function() {
        return chainListInstance.articles(articleId);
      }).then(function(data) {
        assert.equal(data[0].toNumber(), articleId, "article id must be " + articleId);
        assert.equal(data[1], seller, "seller must be " + seller);
        assert.equal(data[2], 0x0, "buyer must be empty");
        assert.equal(data[3], articleName, "article name must be " + articleName);
        assert.equal(data[4], articleDescription, "article description must be " + articleDescription);
        assert.equal(data[5].toNumber(), web3.toWei(articlePrice, "ether"), "article price must be " + web3.toWei(articlePrice, "ether"));
      });
  });

1) Это один из тестовых файлов, которые я видел для своего кода для функции SellArticle, с которой я работал.

2) Насколько мне известно, цепочка обещаний выполняется выводом, данным первым обещанием следующему

3) И он ждет завершения обещания до тех пор, пока он не останется в этой точке

4) .then(assert.fail) как он может перейти к следующему шагу, если нет ошибки и можно обещать пропуск цепочки

пожалуйста, поправьте меня, если я ошибаюсь

Ответы (2)

Тестирование ожидаемых исключений сложно, но также очень важно, так как вы можете подтвердить, что контракт отклоняет все неуместные запросы.

Вы можете найти эту утилиту более полезной. Xavier устранил некоторые тонкие различия в поведении между geth и ganache-cli (testRPC) в модуле, который вы можете импортировать. Это облегчает гораздо более читаемый тест.

https://gist.github.com/xavierlepretre/d5583222fde52ddfbc58b7cfa0d2d0a9

Ваш будет что-то вроде:

it("should throw an exception if you try to buy an article that does not exist", function() {

  return expectedExceptionPromise(function () {
    return chainListInstance.sellArticle(
      articleName, 
      articleDescription, 
      web3.toWei(articlePrice, "ether"), 
        { from: accounts[0], value: 1, gas: 3000000 });
        }, 3000000);

    });
  });
});

Тест будет жаловаться , если возвращаемое значение не является исключением.

Вы могли заметить, что я вырезал новый этап контракта. А beforeEachможет помочь каждому тесту начаться хорошо. Например, настройка chainListInstance.

Надеюсь, поможет.

Обычно я нахожу использование async/await вместо цепочек промисов более читабельным и понятным. Для подтверждения сбоя транзакции вы также можете использовать мою библиотеку truffle-assertions, в которой есть функция специально для этого.

Его можно установить с помощью npm:

npm install truffle-assertions

А затем импортируется вверху вашего файла:

const truffleAssert = require('truffle-assertions');

Используя как async/await, так и truffle-assertions, вы можете заменить свой код следующим, который будет гораздо более кратким.

it("should throw an exception if you try to buy an article that does not exist", async () => {
  let chainListInstance = await ChainList.deployed();
  let receipt = await chainListInstance.sellArticle(articleName, articleDescription, web3.toWei(articlePrice, "ether"), { from: seller });

  truffleAssert.fails(
    chainListInstance.buyArticle(2, { from: buyer, value: web3.toWei(articlePrice, "ether") }),
    truffleAssert.ErrorType.INVALID_OPCODE
  );

  let data = await chainListInstance.articles(articleId);

  assert.equal(data[0].toNumber(), articleId, "article id must be " + articleId);
  assert.equal(data[1], seller, "seller must be " + seller);
  assert.equal(data[2], 0x0, "buyer must be empty");
  assert.equal(data[3], articleName, "article name must be " + articleName);
  assert.equal(data[4], articleDescription, "article description must be " + articleDescription);
  assert.equal(data[5].toNumber(), web3.toWei(articlePrice, "ether"), "article price must be " + web3.toWei(articlePrice, "ether"));
});