首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么这个应许的AssertionError打印到控制台而不是我的摩卡测试跑步者?

为什么这个应许的AssertionError打印到控制台而不是我的摩卡测试跑步者?
EN

Stack Overflow用户
提问于 2015-10-09 22:08:40
回答 1查看 1.5K关注 0票数 3

我将对一些使用chai-as-promisedMocha承诺的代码进行测试。我的测试套件还利用取-模拟模拟通常使用Fetch API发送的AJAX请求。

下面是我要测试的代码:

代码语言:javascript
运行
复制
/**
 * Sends a POST request to save (either insert or update) the record
 * @param  {object} record simple object of column name to column value mappings
 * @return {Promise}       Resolves when the POST request full response has arrived.
 * Rejects if the POST request's response contains an Authorization error.
 */
save(record) {
  var _this = this;
  return this._auth(record)
    .then(function() {
      return window.fetch(_this._getPostUrl(), {
        method: 'post',
        headers: {
          'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        body: _this._objToPostStr(record),
        credentials: 'include'
      });
    })
    .then(function(saveResp) {
      return saveResp.text();
    })
    .then(function(saveResp) {
      return new Promise(function(resolve, reject) {
        if (saveResp.indexOf('Authorization') !== -1) {
          reject('Request failed');
        } else {
          resolve(saveResp);
        }
      });
    });
}

在我最高级的describe中,我有一个函数,它最初设置我的fetchMock对象。

代码语言:javascript
运行
复制
before(() => {
  fetchMock = new FetchMock({
    theGlobal: window,
    Response: window.Response,
    Headers: window.Headers,
    Blob: window.Blob,
    debug: console.log
  });
  fetchMock.registerRoute({
    name: 'auth',
    matcher: /tlist_child_auth.html/,
    response: {
      body: 'authResp',
      opts: {
        status: 200
      }
    }
  });
});

下面是相关的测试代码:

代码语言:javascript
运行
复制
describe('save', () => {
  it('save promise should reject if response contains the string Authorization', () => {

    fetchMock.mock({
      routes: ['auth', {
        name: 'save',
        matcher: /changesrecorded.white.html/,
        response: {
          body: 'Authorization',
          opts: {
            status: 200
          }
        }
      }]
    });

    let _getLocationStub = sinon.stub(client, '_getLocation');
    _getLocationStub.returns('/admin/home.html');

    client.foreignKey = 12345;
    let promise = client.save({
      foo: 'bar'
    });
    promise.should.eventually.be.fulfilled;
    fetchMock.unregisterRoute('save');
  });
});

我在save调用中定义fetchMock.mock()路由的原因是,我还有另一个测试,需要重新定义save路由以返回其他内容。

为了确保所承诺的chai实际上是有效的,并将通知我失败的测试,我编写了一个失败的测试promise.should.eventually.be.fulfilled;。这将失败,因为如果响应包含Authorization,则由Authorization返回的承诺将被拒绝。Chrome控制台显示AssertionError和message: expected promise to be fulfilled but it was rejected with 'Request failed,但是我的Mocha test-runner.html页面显示这个测试通过了。出于某种原因,该承诺与摩卡的沟通不正常。

如果你想看我的整个项目,请看这个回购

知道为什么吗?

编辑:

下面是我的测试设置代码:

代码语言:javascript
运行
复制
let expect = chai.expect;
mocha.setup('bdd');
chai.should();
chai.use(chaiAsPromised);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-12 16:52:22

promise.should.eventually.be.fulfilled值是一个承诺,您应该返回这个值,这样Mocha就可以知道测试结束时的情况。我创建了一个小测试文件来模拟您看到的内容,如果像您一样,我不能返回promise.should.eventually.be.fulfilled;,我就可以完全复制这个行为。下面是一个有用的例子:

代码语言:javascript
运行
复制
import chai from "chai";
import chaiAsPromised from "chai-as-promised";

chai.use(chaiAsPromised);
chai.should();

describe("foo", () => {
    it("bar", () => {
        let promise = Promise.reject(new Error());
        return promise.should.eventually.be.fulfilled;
    });
});

在您的代码中,您在测试的最后有一些清理代码:fetchMock.unregisterRoute('save');。根据您显示的内容,我会将其移到一个after钩子中,以便它能够反映您的before钩子。通常,after应该执行对应于beforeafterEach中的内容与beforeEach中的内容相对应的清理。但是,如果出于某种原因需要在测试中进行清理代码,可以这样做:

代码语言:javascript
运行
复制
        function cleanup() {
            console.log("cleanup");
        }

        return promise.should.eventually.be.fulfilled.then(
            // Called if there is no error, ie. if the promise was
            // fullfilled.
            cleanup,
            // Called if there is an error, ie. if the promise was
            // rejected.
            (err) => { cleanup(); if (err) throw err; });

不幸的是,柴似乎返回了一些看起来像ES6 Promise的东西,但只返回了部分内容。最终,它可能会返回一个实际的ES6承诺,然后无论发生什么情况,您都可以调用.finally来运行清理代码,并使错误自动传播。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33047851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档