다음 테스트는 이상하게 작동합니다.
it('Should return the exchange rates for btc_ltc', function(done) {
var pair = 'btc_ltc';
shapeshift.getRate(pair)
.then(function(data){
expect(data.pair).to.equal(pair);
expect(data.rate).to.have.length(400);
done();
})
.catch(function(err){
//this should really be `.catch` for a failed request, but
//instead it looks like chai is picking this up when a test fails
done(err);
})
});
거부 된 약속을 올바르게 처리하고 테스트하려면 어떻게해야합니까?
실패한 테스트를 어떻게 올바르게 처리해야합니까 (예 : expect(data.rate).to.have.length(400);
?
테스트하고있는 구현은 다음과 같습니다.
var requestp = require('request-promise');
var shapeshift = module.exports = {};
var url = 'http://shapeshift.io';
shapeshift.getRate = function(pair){
return requestp({
url: url + '/rate/' + pair,
json: true
});
};
답변
가장 쉬운 방법은 Mocha의 최신 약속 지원 내장 약속을 사용하는 것입니다.
it('Should return the exchange rates for btc_ltc', function() { // no done
var pair = 'btc_ltc';
// note the return
return shapeshift.getRate(pair).then(function(data){
expect(data.pair).to.equal(pair);
expect(data.rate).to.have.length(400);
});// no catch, it'll figure it out since the promise is rejected
});
또는 현대 노드와 async / await :
it('Should return the exchange rates for btc_ltc', async () => { // no done
const pair = 'btc_ltc';
const data = await shapeshift.getRate(pair);
expect(data.pair).to.equal(pair);
expect(data.rate).to.have.length(400);
});
이 접근 방식은 엔드 투 엔드 약속이므로 테스트하기가 더 쉬우 며 done()
어디에서나 이상한 전화 처럼 생각하는 이상한 경우에 대해 생각할 필요가 없습니다 .
이것은 현재 Mocha가 Jasmine과 같은 다른 라이브러리보다 장점입니다. 당신은 또한 확인 할 수 있습니다 차이로이 약속 이 더 쉽게 (더하지 않습니다 것이다 .then
)하지만 개인적으로는 현재 버전의 명확성과 단순성을 선호
답변
이미 지적한 바와 같이 여기 , 모카의 최신 버전은 이미 약속-알고 있습니다. 그러나 OP가 Chai에 대해 구체적으로 물었으므로 chai-as-promised
약속을 테스트하기위한 깔끔한 구문을 제공하는 패키지 를 지적하는 것이 공평합니다 .
약속 된 차이를 사용하여
약속의 약속을 사용 하여 약속에 대한 사례 resolve
와 reject
사례를 모두 테스트하는 방법은 다음과 같습니다 .
var chai = require('chai');
var expect = chai.expect;
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
...
it('resolves as promised', function() {
return expect(Promise.resolve('woof')).to.eventually.equal('woof');
});
it('rejects as promised', function() {
return expect(Promise.reject('caw')).to.be.rejectedWith('caw');
});
약속 된 차이없이
테스트 대상에 대해 명확히하기 위해 다음은 약속의 여지없이 코딩 된 동일한 예제입니다.
it('resolves as promised', function() {
return Promise.resolve("woof")
.then(function(m) { expect(m).to.equal('woof'); })
.catch(function(m) { throw new Error('was not supposed to fail'); })
;
});
it('rejects as promised', function() {
return Promise.reject("caw")
.then(function(m) { throw new Error('was not supposed to succeed'); })
.catch(function(m) { expect(m).to.equal('caw'); })
;
});
답변
여기 내 테이크가있다 :
- 사용
async/await
- 추가 차이 모듈이 필요하지 않음
- 캐치 문제를 피하면서 @TheCrazyProgrammer는 위에서 지적했습니다.
지연된 약속 기능. 지연 시간이 0 인 경우 실패합니다.
const timeoutPromise = (time) => {
return new Promise((resolve, reject) => {
if (time === 0)
reject({ 'message': 'invalid time 0' })
setTimeout(() => resolve('done', time))
})
}
// ↓ ↓ ↓
it('promise selftest', async () => {
// positive test
let r = await timeoutPromise(500)
assert.equal(r, 'done')
// negative test
try {
await timeoutPromise(0)
// a failing assert here is a bad idea, since it would lead into the catch clause…
} catch (err) {
// optional, check for specific error (or error.type, error. message to contain …)
assert.deepEqual(err, { 'message': 'invalid time 0' })
return // this is important
}
assert.isOk(false, 'timeOut must throw')
log('last')
})
긍정적 인 테스트 는 다소 간단합니다. 500→0
거부 된 약속이 에스컬레이션되면 예기치 않은 실패 (by by simulate )가 테스트에 자동으로 실패합니다.
부정적인 테스트 는 try-catch-idea를 사용합니다. 그러나 원치 않는 패스에 대한 ‘신고’는 catch 절 이후에만 발생합니다 (그러면 catch () 절에서 끝나지 않아 잘못된 오류를 유발합니다.
이 전략이 작동하려면 catch 절에서 테스트를 반환해야합니다. 다른 것을 테스트하지 않으려면 다른 it ()-block을 사용하십시오.
답변
더 나은 솔루션입니다. catch 블록에서 done으로 오류를 반환하십시오.
// ...
it('fail', (done) => {
// any async call that will return a Promise
ajaxJson({})
.then((req) => {
expect(1).to.equal(11); //this will throw a error
done(); //this will resove the test if there is no error
}).catch((e) => {
done(e); //this will catch the thrown error
});
});
이 테스트는 다음 메시지와 함께 실패합니다. AssertionError: expected 1 to equal 11