为什么 mocha 不会像承诺的那样等待 chai 完成?

Why wont mocha wait for chai as promised to finish?

我正在尝试使用 selenium、mocha 和 chai-as-promised 测试 Web 应用程序。我似乎无法让 mocha 等待 chai-as-promised 断言得到解决。我的测试代码如下所示:

var selenium = require('selenium-webdriver')
var By = selenium.By
var chai = require('chai')
var cap = require('chai-as-promised')
chai.use(cap)
expect = chai.expect

describe('Test Group', function() {
  var driver
  before(function() {
    driver = new selenium.Builder()
      .withCapabilities(selenium.Capabilities.chrome())
      .build()
    driver.getWindowHandle()
  })

  after(function() {
    driver.sleep(500).then(function() {
      driver.quit()
    })
  })

  describe('Authentication', function() {
    describe('#login redirect', function() {
      it('should redirect to /users/login when not logged in', function() {
        driver.get('http://127.0.0.1:3000/')
        driver.sleep(500).then(function() {
          return expect(driver.getCurrentUrl()).to.eventually.contain('WONT CONTAIN THIS')
        })
      })
    })
  })
})

测试总是通过,尽管断言无法通过。测试 return 这些错误以及:

  Test Group
    Authentication
      #login redirect
        ✓ should redirect to /users/login when not logged in


  1 passing (34ms)

(node:24883) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: expected 'http://127.0.0.1:3000/users/login' to include 'WONT CONTAIN THIS'
(node:24883) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

有两种方法可以使 mocha 测试异步。

  1. 使用测试函数的第一个参数:done.
  2. 返回承诺

在这里您可以阅读更多关于 Mocha Asynchronous Tests 的信息。

在您的情况下,您已经在使用承诺,因此最简单的解决方案是 return 您的承诺。像这样:

  it('should redirect to /users/login when not logged in', function() {
    driver.get('http://127.0.0.1:3000/')
    return driver.sleep(500).then(function() { // <------- return this promise
      return expect(driver.getCurrentUrl()).to.eventually.contain('WONT CONTAIN THIS')
    })
  })

这也与您的 after 功能有关。按照现在的写法,after 函数将在内部 promise 解析之前完成。你可以像这样让它异步:

  after(function() {
    return driver.sleep(500).then(function() {
      driver.quit()
    })
  })

请注意,如果 driver.quit() return 是一个承诺,您可能也应该 return 那。