programing

어떻게 하면 모카와 차이와의 약속을 제대로 테스트할 수 있습니까?

lovecodes 2023. 8. 13. 10:27
반응형

어떻게 하면 모카와 차이와의 약속을 제대로 테스트할 수 있습니까?

다음 테스트가 이상하게 작동합니다.

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
});

또는 최신 노드 및 비동기/대기 기능을 사용할 경우:

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()여기저기서 전화가 걸려옵니다.

이것은 현재 모카가 자스민과 같은 다른 도서관들에 비해 가지고 있는 장점입니다.당신은 또한 Chai As Promise를 확인하는 것이 더 쉬울 것입니다 (아니오)..then하지만 저는 개인적으로 현재 버전의 명확성과 단순성을 선호합니다.

여기서 이미 지적했듯이, 최신 버전의 Mocha는 이미 Promise를 인식하고 있습니다.하지만 OP가 차이에 대해 구체적으로 물었기 때문에, 그것을 지적하는 것은 정당합니다.chai-as-promised약속 테스트를 위한 깨끗한 구문을 제공하는 패키지:

chai-as-capture 사용

다음은 약속된 차이를 사용하여 두 가지를 모두 테스트하는 방법입니다.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');
});

태연하게

테스트 대상을 확실히 하기 위해 다음은 chai-as-promise 없이 코드화된 동일한 예입니다.

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
  • 추가 차이 모듈이 필요하지 않음
  • "캐치 이슈를 피하는 것"이라고 위에서 지적한 @크레이지 프로그래머"

지연이 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)는 거부된 약속이 증가함에 따라 자동으로 테스트에 실패합니다.

음성 테스트는 시도-캐치-아이디어를 사용합니다.그러나: 원하지 않는 패스에 대한 '불만'은 catch 절 이후에만 발생합니다(그러면 catch() 절에 끝나지 않고 추가적이지만 오해를 불러일으키는 오류가 발생합니다).

이 전략이 작동하려면 catch 절에서 검정을 반환해야 합니다.다른 항목을 테스트하지 않으려면 다른 it()-block을 사용합니다.

더 나은 해결책이 있습니다.캐치 블록에서 완료된 오류만 반환합니다.

// ...

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

언급URL : https://stackoverflow.com/questions/26571328/how-do-i-properly-test-promises-with-mocha-and-chai

반응형