当前位置: 首页 > 知识库问答 >
问题:

我如何正确地测试摩卡和柴的promise?

孙明德
2023-03-14

以下测试表现异常:

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

我应该如何正确处理被拒绝的promise(并测试它)?

如何正确处理失败的测试(即:expect(data.rate))。到有长度(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
    });
};

共有3个答案

张嘉佑
2023-03-14
  • 使用async/await
  • 不需要额外的chai模块
  • “避免捕获问题,”Crazyprogrammer在上面指出

延迟promise函数,如果延迟为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模拟)将自动失败测试,因为拒绝的promise升级。

否定测试使用了“尝试捕捉”的想法。但是,只有在catch子句之后才会对不希望的传递进行“抱怨”(这样,它就不会出现在catch()子句中,从而触发进一步但误导性的错误)。

要使此策略起作用,必须从catch子句返回测试。如果不想测试任何其他内容,请使用另一个it()-块。

詹正浩
2023-03-14

正如这里已经指出的,摩卡的新版本已经知道promise。但是由于OP特别询问了chai,所以指出chai as-promise的包为测试promise提供了一个干净的语法是公平的:

下面是您如何使用chai-as-promise来测试promise的解决拒绝案例:

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-aspromise:

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'); })
            ;
});
岳枫
2023-03-14

最简单的方法是使用Mocha在最新版本中提供的内置promise支持:

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

因为这种方法是端到端的promise,所以测试起来更容易,你不必考虑你正在考虑的奇怪的情况,比如到处都是奇怪的do()调用。

这是摩卡目前相对于茉莉等其他图书馆的优势。你可能还想检查柴作为promise,这将使它更容易(没有。然后),但我个人更喜欢当前版本的清晰和简单

 类似资料:
  • 问题内容: 以下测试的行为异常: 我应该如何正确处理被拒绝的承诺(并进行测试)? 我应该如何正确处理失败的测试(即:? 这是我正在测试的实现: 问题答案: 最简单的方法是使用Mocha在最新版本中提供的内置Promise支持: 或者使用现代Node和async / await: 因为这种方法是端到端的承诺,所以它更易于测试,您不必考虑正在考虑的奇怪情况,就像到处都是奇怪的电话一样。 这是Mocha

  • 我正在尝试从请求模块测试GET HTTP方法: 下面是我如何测试 部分的: 但是,我没有找到测试catch部分的方法(当它给出错误并且响应状态不是>=400)。 有什么建议吗? 它也将帮助我解决这个问题,一个简单的例子,另一个代码测试一个承诺的catch部分。

  • 问题内容: Mocha尝试在默认情况下查找测试文件,如何指定另一个目录,例如? 问题答案: 编辑:不建议使用此选项:https://mochajs.org/#mochaopts 如果要通过仍然仅在命令行上运行但要在文件夹而不是中运行测试来执行此操作,请在文件中创建一个文件,其中包含以下内容: 如果要运行该文件夹和子目录中的所有内容,请将其放入 是通过命令行传递的参数,因此使第一行也就是您要更改测试

  • 我正在使用对示例项目进行单元测试。然后是下面的参考。 https://www.sitepoint.com/unit-test-javascript-mocha-chai/ 我可以使用终端成功地运行测试。它显示成功/失败测试状态。但是,不生成测试报告。 我在终端中使用了下面的命令来运行测试 如何生成测试报告。

  • 我刚开始学摩卡和茶。而我被困在这里 基于以上代码,现在我有两个问题 > 如果我想使用上面的代码完成并取消注释完成(),那么它会出错 超过了2000毫秒的超时时间。对于异步测试和挂钩,确保调用“done()”;如果返回promise,请确保它已解决。

  • 我正在使用mocha和chai对AngularJS服务执行一些单元测试。该服务具有不同的功能,每个功能都返回一个promise。 我面临的问题是,测试不是在断言之前等待promise值得到解决。我知道做()回调可以用摩卡。所以,我试着用它。但这也给了我一个错误。这是代码: 因此,现在的问题是测试没有失败(它应该失败)。相反,它只是超时并给我一个错误:“超时超过2000ms。请确保在此测试中调用了d