2014-06-05 4 views
5

저는 단위 테스트, mocha 및 should.js에 익숙하지 않으며 약속을 반환하는 비동기 메서드에 대한 테스트를 작성하려고합니다. 여기 내 테스트 코드입니다 : 내가 수동으로 tideRetriever.get 방법을 테스트 할 때should.js는 모카 테스트 실패를 야기하지 않습니다.

var should = require("should"), 
    tideRetriever = require("../tide-retriever"), 
    moment = require("moment"), 
    timeFormat = "YYYY-MM-DD-HH:mm:ss", 
    from = moment("2013-03-06T00:00:00", timeFormat), 
    to = moment("2013-03-12T23:59:00", timeFormat), 
    expectedCount = 300; 

describe("tide retriever", function() { 
    it("should retrieve and parse tide CSV data", function() { 
     tideRetriever.get(from, to).then(
      function(entries) { // resolve 
       entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
      }, 
      function(err) { // reject 
       should.fail("Promise rejected", err); 
      } 
     ); 
    }); 
}); 

, 그것은 지속적으로 (예상대로) (27 개) 요소의 배열을 해결하지만, 시험에 관계없이 expectedCount의 가치를 실패하지 않습니다. 다음은 간단한 수동 테스트입니다.

tideRetriever.get(from, to).then(
    function(entries) { 
     console.log(entries, entries.length); 
    }, 
    function(err) { 
     console.log("Promise rejected", err); 
    } 
); 

또한 필요한 경우 테스트중인 모듈의 소스를 게시 할 수도 있습니다.

나는 모카 또는 should.js에 대해 오해하고 있습니까? 어떤 도움이라도 대단히 감사하겠습니다.

답변

7

UPDATE

모카 테스트에서 Promise을 반환하는 대신 done() 콜백을 추가 지원하기 시작했다. 원래 대답은 여전히 ​​작동하지만 테스트는이 방법으로 많은 청소기 같습니다 완벽한 예를 들어

it("should retrieve and parse tide CSV data", function() { 
    return tideRetriever.get(from, to).then(
     function(entries) { 
      entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
     } 
    ); 
}); 

체크 아웃 this gist.

ORIGINAL

주의. 수락 된 대답은 일반적인 비동기 코드에서만 작동하며 Promises (작성자가 사용함)와는 작동하지 않습니다.

차이점은 Promise 콜백에서 던진 예외는 응용 프로그램 (이 경우에는 모카)에서 포착 할 수 없으므로 실제 어설 션이 아닌 시간 초과로 테스트가 실패합니다. 어설 션은 Promise 구현에 따라 기록되거나 기록되지 않을 수 있습니다. when documentation에서 자세한 내용을 참조하십시오.

약속을 올바르게 처리하려면 err 개체를 던지기보다는 done() 콜백에 전달해야합니다. 동일한 메서드의 onFulfilment() 콜백에서 예외를 catch하지 않으므로 메서드를 사용하여 수행 할 수 있습니다 (onRejection() 콜백이 아닌 Promise.then()).done() 콜백 가능한 모든 경우를 충당하기 위해 세 곳에서 사용

describe("tide retriever", function() { 
    it("should retrieve and parse tide CSV data", function(done) { 
     tideRetriever.get(from, to).then(
      function(entries) { // resolve 
       entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
       done(); // test passes 
      }, 
      function(err) { // reject 
       done(err); // Promise rejected 
      } 
     ).catch(function (err) { 
      done(err); // should throwed assertion 
     }); 
    }); 
}); 

PS : 아래의 예를 참조하십시오. 그러나 onRejection() 콜백은 특별한 논리가 필요하지 않으면 완전히 제거 할 수 있습니다. Promise.catch()은이 경우에도 거부를 처리합니다.

+0

기능의 매개 변수로 "done"을 추가하는 것을 잊어 버렸습니다. – Chaoste

+0

@Chaoste thanks, fixed. –

4

비동기 코드를 테스트 할 때 테스트가 완료되면 (통과했는지 실패했는지 여부에 관계없이) 모카에게 알려야합니다. 이것은 모카가 done 함수로 채우는 테스트 함수의 인수를 지정하여 수행됩니다. 그래서 코드는 다음과 같습니다 방법이 모카는이 비동기 테스트이며이 done()은 그냥 인수를 지정하는 것입니다 호출 될 때까지 기다릴 필요가 알고

describe("tide retriever", function() { 
    it("should retrieve and parse tide CSV data", function(done) { 
     tideRetriever.get(from, to).then(
      function(entries) { // resolve 
       entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
       done(); 
      }, 
      function(err) { // reject 
       should.fail("Promise rejected", err); 
       done(); 
      } 
     ); 
    }); 
}); 

참고.

또한 성공 및 실패시 모두 발생하는 "완료된"처리기가있는 경우 done()을 호출하여 호출을 저장할 수 있습니다.

더 많은 정보는에서 : 어떤 점에서 http://mochajs.github.io/mocha/#asynchronous-code

+0

감사합니다. 'done' 함수는 테스트가 다른 테스트와 동 기적으로 실행되어야하는지 여부를 지정하기위한 것이라고 생각했습니다. – SimpleJ

+0

내가 할 수 있으면 나는 이것을 두 배 upvote 것이다. 'done' arg를 테스트에 전달하는 것의 중요성 ('콜백 함수 ')은 놓치기 쉽지만, 혼란의 원인이됩니다! – Ben