[javascript] Mocha / Chai expect.to.throw는 던진 오류를 포착하지 않습니다.

Chai가 expect.to.thrownode.js 앱 테스트에서 작동하는 데 문제가 있습니다. 테스트는 던진 오류에서 계속 실패하지만 테스트 케이스를 랩하여 시도하고 잡은 오류를 주장하면 작동합니다.

않는 expect.to.throw나는 그것을해야 또는 뭔가 생각처럼 작동하지?

it('should throw an error if you try to get an undefined property', function (done) {
  var params = { a: 'test', b: 'test', c: 'test' };
  var model = new TestModel(MOCK_REQUEST, params);

  // neither of these work
  expect(model.get('z')).to.throw('Property does not exist in model schema.');
  expect(model.get('z')).to.throw(new Error('Property does not exist in model schema.'));

  // this works
  try {
    model.get('z');
  }
  catch(err) {
    expect(err).to.eql(new Error('Property does not exist in model schema.'));
  }

  done();
});

실패:

19 passing (25ms)
  1 failing

  1) Model Base should throw an error if you try to get an undefined property:
     Error: Property does not exist in model schema.



답변

에 함수를 전달해야합니다 expect. 이처럼 :

expect(model.get.bind(model, 'z')).to.throw('Property does not exist in model schema.');
expect(model.get.bind(model, 'z')).to.throw(new Error('Property does not exist in model schema.'));

당신이 그것을하는 방식으로, 당신은 전화 expect결과 로 전달됩니다 model.get('z'). 하지만 뭔가 발생 여부를 테스트하려면에 기능 통과해야 expect, expect자신을 호출됩니다. bind상기 이용 방법은 호출이라는 새로운 함수 생성 model.get하여 this값으로 설정 model하고 내지 제 인수 세트 'z'.

의 좋은 설명은 bind찾을 수 있습니다 여기에 .


답변

이 답변 에서 알 수 있듯이 다음 과 같이 익명 함수로 코드를 래핑 할 수도 있습니다.

expect(function(){
    model.get('z');
}).to.throw('Property does not exist in model schema.');


답변

그리고 이미 ES6 / ES2015를 사용하고 있다면 화살표 기능을 사용할 수도 있습니다. 기본적으로 일반적인 익명 함수를 사용하는 것과 동일하지만 더 짧습니다.

expect(() => model.get('z')).to.throw('Property does not exist in model schema.');


답변

이 질문에는 Chai 어설 션 라이브러리를 언급하지 않은 질문을 포함하여 많은 중복 항목이 있습니다. 다음은 기본적으로 수집 된 것입니다.

어설 션은 즉시 평가하는 대신 함수를 호출해야합니다.

assert.throws(x.y.z);
   // FAIL.  x.y.z throws an exception, which immediately exits the
   // enclosing block, so assert.throw() not called.
assert.throws(()=>x.y.z);
   // assert.throw() is called with a function, which only throws
   // when assert.throw executes the function.
assert.throws(function () { x.y.z });
   // if you cannot use ES6 at work
function badReference() { x.y.z }; assert.throws(badReference);
   // for the verbose
assert.throws(()=>model.get(z));
   // the specific example given.
homegrownAssertThrows(model.get, z);
   //  a style common in Python, but not in JavaScript

어설 션 라이브러리를 사용하여 특정 오류를 확인할 수 있습니다.

마디

  assert.throws(() => x.y.z);
  assert.throws(() => x.y.z, ReferenceError);
  assert.throws(() => x.y.z, ReferenceError, /is not defined/);
  assert.throws(() => x.y.z, /is not defined/);
  assert.doesNotThrow(() => 42);
  assert.throws(() => x.y.z, Error);
  assert.throws(() => model.get.z, /Property does not exist in model schema./)

할까요

  should.throws(() => x.y.z);
  should.throws(() => x.y.z, ReferenceError);
  should.throws(() => x.y.z, ReferenceError, /is not defined/);
  should.throws(() => x.y.z, /is not defined/);
  should.doesNotThrow(() => 42);
  should.throws(() => x.y.z, Error);
  should.throws(() => model.get.z, /Property does not exist in model schema./)

차이 기대

  expect(() => x.y.z).to.throw();
  expect(() => x.y.z).to.throw(ReferenceError);
  expect(() => x.y.z).to.throw(ReferenceError, /is not defined/);
  expect(() => x.y.z).to.throw(/is not defined/);
  expect(() => 42).not.to.throw();
  expect(() => x.y.z).to.throw(Error);
  expect(() => model.get.z).to.throw(/Property does not exist in model schema./);

테스트를 ‘탈출’하는 예외를 처리해야합니다.

it('should handle escaped errors', function () {
  try {
    expect(() => x.y.z).not.to.throw(RangeError);
  } catch (err) {
    expect(err).to.be.a(ReferenceError);
  }
});

처음에는 혼란스러워 보일 수 있습니다. 자전거를 타는 것처럼, 클릭하면 영원히 ‘클릭’합니다.


답변

doc의 예 …;)

this문맥에 의존하기 때문에 :

  • 함수가 .throw에 의해 호출되면 손실됩니다.
  • 이것이 무엇인지 알 방법이 없습니다

다음 옵션 중 하나를 사용해야합니다.

  • 메소드 또는 함수 호출을 다른 함수 안에
  • 바인드 컨텍스트

    // wrap the method or function call inside of another function
    expect(function () { cat.meow(); }).to.throw();  // Function expression
    expect(() => cat.meow()).to.throw();             // ES6 arrow function
    
    // bind the context
    expect(cat.meow.bind(cat)).to.throw();           // Bind

답변

기대하는 점을 () 수 있도록하는 데 도움이 또 다른 가능한 구현의 .bind () 솔루션보다 더 복잡하지만 하나가 제공하는 기능을 필요로 this적용 대상 기능에 컨텍스트, 당신은을 사용할 수 있습니다 call(), 예를 들어,

expect(function() {model.get.call(model, 'z');}).to.throw('...');


답변

나는 그 주위에 좋은 방법을 찾았습니다.

// The test, BDD style
it ("unsupported site", () => {
    The.function(myFunc)
    .with.arguments({url:"https://www.ebay.com/"})
    .should.throw(/unsupported/);
});


// The function that does the magic: (lang:TypeScript)
export const The = {
    'function': (func:Function) => ({
        'with': ({
            'arguments': function (...args:any) {
                return () => func(...args);
            }
        })
    })
};

이전 버전보다 훨씬 읽기 쉽습니다.

it ("unsupported site", () => {
    const args = {url:"https://www.ebay.com/"}; //Arrange
    function check_unsupported_site() { myFunc(args) } //Act
    check_unsupported_site.should.throw(/unsupported/) //Assert
});