[javascript] Jasmine에서 오류가 발생할 것으로 예상되는 테스트를 작성하는 방법은 무엇입니까?

오류가 예상되는 Jasmine Test Framework에 대한 테스트를 작성하려고합니다 . 현재 GitHubJasmine Node.js 통합을 사용하고 있습니다 .

내 노드 모듈에는 다음 코드가 있습니다.

throw new Error("Parsing is not possible");

이제이 오류가 예상되는 테스트를 작성하려고합니다.

describe('my suite...', function() {
    [..]
    it('should not parse foo', function() {
    [..]
        expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));
    });
});

나는 또한 Error()다른 변형을 시도했지만 어떻게 작동시키는 지 알 수 없습니다.



답변

함수를 expect(...)호출에 전달해야합니다 . 여기있는 코드 :

// incorrect:
expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));

실제로하려고 전화 parser.parse(raw) 로 결과를 전달하는 시도 expect(...),

대신 익명 함수를 사용해보십시오.

expect( function(){ parser.parse(raw); } ).toThrow(new Error("Parsing is not possible"));


답변

당신은 사용하고 있습니다 :

expect(fn).toThrow(e)

그러나 함수 주석을 살펴보면 문자열이 예상됩니다.

294 /**
295  * Matcher that checks that the expected exception was thrown by the actual.
296  *
297  * @param {String} expected
298  */
299 jasmine.Matchers.prototype.toThrow = function(expected) {

람다-익명 함수를 사용하여 다음과 같이 작성해야한다고 가정합니다.

expect(function() { parser.parse(raw); } ).toThrow("Parsing is not possible");

이것은 다음 예에서 확인됩니다.

expect(function () {throw new Error("Parsing is not possible")}).toThrow("Parsing is not possible");

Douglas Crockford는 “throw new Error ()”(프로토 타이핑 방식)를 사용하는 대신이 접근 방식을 강력히 권장합니다.

throw {
   name: "Error",
   message: "Parsing is not possible"
}


답변

유일한 목적을 가진 익명의 기능을 만드는 것보다 더 우아한 해결책은 es5의 bind기능 을 사용하는 것 입니다. 바인드 함수는 호출 될 때 this키워드가 제공된 값으로 설정되고 새 함수가 호출 될 때 지정된 인수 시퀀스가 ​​앞에 오는 새 함수를 작성합니다.

대신에:

expect(function () { parser.parse(raw, config); } ).toThrow("Parsing is not possible");

치다:

expect(parser.parse.bind(parser, raw, config)).toThrow("Parsing is not possible");

바인드 구문을 사용하면 다른 this값으로 함수를 테스트 할 수 있으며 내 의견으로는 테스트를 더 읽기 쉽게 만듭니다. 참조 : https://stackoverflow.com/a/13233194/1248889


답변

Jasmine의 toThrow 매처를 다음으로 바꾸면 예외의 name 속성 또는 message 속성과 일치시킬 수 있습니다. 나에게 이것은 다음을 수행 할 수 있기 때문에 테스트를보다 쉽게 ​​작성하고 덜 취성있게 만듭니다.

throw {
   name: "NoActionProvided",
   message: "Please specify an 'action' property when configuring the action map."
}

그런 다음 다음을 사용하여 테스트하십시오.

expect (function () {
   .. do something
}).toThrow ("NoActionProvided");

이것은 중요한 예외가 예상되는 유형의 예외를 던질 때 테스트를 중단하지 않고 나중에 예외 메시지를 조정할 수있게합니다.

이것은 이것을 허용하는 toThrow를 대체합니다.

jasmine.Matchers.prototype.toThrow = function(expected) {
  var result = false;
  var exception;
  if (typeof this.actual != 'function') {
    throw new Error('Actual is not a function');
  }
  try {
    this.actual();
  } catch (e) {
    exception = e;
  }
  if (exception) {
      result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected) || this.env.equals_(exception.name, expected));
  }

  var not = this.isNot ? "not " : "";

  this.message = function() {
    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
      return ["Expected function " + not + "to throw", expected ? expected.name || expected.message || expected : " an exception", ", but it threw", exception.name || exception.message || exception].join(' ');
    } else {
      return "Expected function to throw an exception.";
    }
  };

  return result;
};


답변

앞에서 언급했듯이 함수는 toThrow테스트에서 설명하는 함수이므로 전달해야합니다 . “이 함수는 x를 던질 것으로 예상합니다.”

expect(() => parser.parse(raw))
  .toThrow(new Error('Parsing is not possible'));

사용하는 경우 재스민-매처 (Matchers)을 가 상황에 맞게 때 당신은 또한 다음 중 하나를 사용할 수 있습니다;

// I just want to know that an error was
// thrown and nothing more about it
expect(() => parser.parse(raw))
  .toThrowAnyError();

또는

// I just want to know that an error of 
// a given type was thrown and nothing more
expect(() => parser.parse(raw))
  .toThrowErrorOfType(TypeError);


답변

나는 그것이 더 많은 코드라는 것을 알고 있지만 당신은 또한 할 수 있습니다 :

try
   do something
   @fail Error("should send a Exception")
 catch e
   expect(e.name).toBe "BLA_ERROR"
   expect(e.message).toBe 'Message'


답변

커피 스크립트 애호가

expect( => someMethodCall(arg1, arg2)).toThrow()