Ловить брошенные ошибки с SinonJS


У меня есть метод, который может выдать ошибку, но у меня возникли проблемы с написанием sinonjs/Mocha/Should unit test case для этого условия.

Образец тестируемой функции:

function testError(value) {
  if (!value) {
    throw new Error('No value');
    return false;
  }
};

Образец теста:

describe('#testError', function() {
  it('throws an error', function() {
    var spy = sinon.spy(testError);
    testError(false);
    spy.threw().should.be.true();
  });
});

Это выводит:

  #testError
    1) throws an error


  0 passing (11ms)
  1 failing

  1) #testError throws an error:
     Error: No value
      at testError (tests/unit/js/test-error.js:6:14)
      at Context.<anonymous> (tests/unit/js/test-error.js:14:6)

Я ожидал, что Синон поймает ошибку и позволит мне шпионить за броском, но вместо этого он, похоже, провалил тест. Есть идеи?

Я сослался на не Синон.Яш шпионы перехватывать ошибки? но единственное решение, которое можно использовать expect. Я бы предпочел, если это возможно, сохранить одну библиотеку утверждений.

2 3

2 ответа:

Похоже, что это работает внутри a try/catch:

function foo() { throw new Error("hey!"); }
var fooSpy = sinon.spy(foo);
try {
  fooSpy();
} catch (e) {
  // pass
}
assert(fooSpy.threw());

Обратите внимание, что вы должны позвонить fooSpy, нет foo сам по себе.

Но также обратите внимание, что .should.be.true() не является частью Синона, поэтому вы, вероятно, уже используете Chai или аналогичную библиотеку, и в этом случае синтаксисexpect(foo).to.have.thrown() или assert.throws(foo, someError) кажется намного лучше.

Update: Если вы используете ShouldJS, похоже, вы можете использовать should.throws. Я все еще думаю, что это лучше, чем использовать версию Синон для этого цель.

Пересмотрено

Следуя полезному совету @nrabinowitz, вот решение, которое использует should.throws. Это позволяет полностью избежать использования Sinon.spy.
describe('#testError', function() {
  it('throws an error', function() {
    should.throws(function() {
      testError(false);
    });
  });
});