mocha测试_如何使用Mocha,Chai和SinonJS测试NodeJS应用

mocha测试

Not having tests in your app is a pain because, chances are every time you make slight adjustments to your app you have to manually check every single part of your app to see if anything broke. Writing tests however, also feels for the most part a chore. But we definitely need them.

在您的应用程序中不进行测试是很痛苦的,因为每次您对应用程序进行细微调整时,您都必须手动检查应用程序的每个部分以查看是否有任何损坏。 但是,编写测试在大多数情况下也让人感到烦琐。 但是我们绝对需要它们。

Why the fuss around automated testing? With automated tests you don't have to test all the workings of the app every time you change something in your enormous and still growing app. This means that when you are adding or modifying parts of your app, you will have a lot more confidence in the reliablity of your code. Which is really reassuring.

为什么在自动化测试中大惊小怪? 使用自动化测试,您不必每次在庞大且仍在增长的应用程序中进行更改时就测试应用程序的所有运行情况。 这意味着,当您添加或修改应用程序的各个部分时,您将对代码的可靠性更有信心。 这真的让人放心。

In this article, we'll look into testing node apps. We'll use Mocha, Chai and SinonJS, and delve into using spies, stubs and mocks. You'll need to be familiar with NodeJS and Javascript, to get the most out of this. Enjoy!

在本文中,我们将研究测试节点应用程序。 我们将使用Mocha,Chai和SinonJS,并深入研究使用间谍,存根和模拟。 您需要熟悉NodeJS和Javascript,才能充分利用这一点。 请享用!

工具文献 ( Literature on Tools )

摩卡咖啡 (Mocha)

Mocha is a test runner. This just means that it is a tool that runs/executes our tests. The tests themselves aren't written in Mocha. Other test runners include; Jasmine, Jest.

摩卡(Mocha)是一名测试选手。 这只是意味着它是运行/执行我们的测试的工具。 测试本身不是用Mocha编写的。 其他测试选手包括; 茉莉,开玩笑。

Let's install mocha globally to be able to use it on our command line:

让我们全局安装mocha以便能够在命令行上使用它:

> npm install -g mocha

Create our new directory for our app:

为我们的应用程序创建新目录:

> mkdir testing-async-code && cd testing-async-code
> npm init
> npm install --save mocha
> mkdir tests

Then add a basic test just to see how Mocha works; for now we'll use Assert as our assertion library which comes in NodeJS so no npm install needed.

然后添加一个基本测试,以了解Mocha的工作方式; 现在,我们将使用Assert作为Assert中的断言库,因此不需要npm install

const assert = require("assert");

describe("smoke test", function() {
  it("checks equality", function() {
    assert.equal(true, true);
  });
});

To run this we just run the command mocha and pass in the location of our tests:

要运行此命令,我们只需运行命令mocha并传递测试位置:

> mocha tests/

Yay, our test passes. What essentially happens is that the assert tests something, if the test passes it doesn't do anything; if it fails it throws an exception and this stops your tests. Just to see how a failure would look like we can change the line to something that would fail.

是的,我们的测试通过了。 本质上发生的是, assert测试某项内容,如果测试通过,则它不执行任何操作。 如果失败,则抛出异常,这将停止测试。 只是为了看看失败的样子,我们可以将线路更改为可能失败的行。

const assert = require("assert");

describe("smoke test", function() {
  it("checks equality", function() {
    assert.equal(true, false);
  });
});

Notice our tests stop and we get an error message telling us we have an AssertionError and what is expected. Assert, throws an error and that is how Mocha knows whether our tests are failing or passing.

注意我们的测试停止了,我们收到一条错误消息,告诉我们我们有一个AssertionError以及期望的结果。 断言,引发错误,这就是Mocha如何知道我们的测试是失败还是通过。

Note: For the entire article we wont use arrow functions. Why? You ask: Well, with Mocha you can access its context using this keyword. So, for example if you wanted to extend timeout for a test which is normally 2000ms you could do something like; this.timeout(5000). When using arrow functions, it makes this bound to the lexical context not the Mocha context. This is all to say that doing something like this.timeout(5000) won't work while using the ES6 arrow functions, along with all the other stuff you can do with this in Mocha. You can read more on this here.

注意:对于整篇文章,我们将不使用箭头功能。 为什么? 您会问:好吧,通过Mocha,您可以使用this关键字访问其上下文。 因此,例如,如果您想延长测试的超时时间(通常为2000毫秒),则可以执行以下操作: this.timeout(5000) 。 当使用箭头功能,它使this势必词汇语境不是摩卡上下文。 就是说,使用ES6箭头功能以及在Mocha中可以使用this功能完成的所有其他操作时,执行this.timeout(5000)将无效。 您可以在此处阅读更多内容。

hai (Chai)

Chai is an assertion library. So far, we have just used Assert to make assertions and we have an idea of what asserts do. Chai, does the exact same thing but allows for better readability.

Chai是一个断言库。 到目前为止,我们仅使用Assert进行断言,并且对断言的作用有所了解。 柴,做同样的事情,但允许更好的可读性。

Let's install it:

让我们安装它:

> npm i --save-dev chai

Now we can change our smoke test to read like this:

现在,我们可以将烟雾测试更改为:

const chai = require("chai");
const expect = chai.expect;

describe("smoke test", function() {
  it("checks equality", function() {
    expect(true).to.be.true;
  });
});

SinonJS (SinonJS)

SinonJS provides stand alone test spies, stubs and mocks. This is the mechanism we'll be using to create our spies, stubs and mocks.

SinonJS提供了独立的测试间谍,存根和模拟 。 这是我们用来创建间谍,存根和模拟的机制。

> npm i --save-dev sinon

Spies: Creates fake functions which we can use to track executions. This means we can tell/ find out whether the function has been executed/ how many times its been called etc. We can also use spies on existing functions and get the same capability, to track those functions executions. We'll see this in action a bit later.

间谍:创建可用于跟踪执行的伪函数。 这意味着我们可以告诉/查明该函数是否已执行/被调用了多少次,等等。我们还可以对现有函数使用间谍并获得相同的功能来跟踪那些函数的执行。 我们将在稍后看到实际效果。

Stubs: Enables us to replace functions. This gives us more control. We can return whatever we want or have our functions work in a way that suites us to be able to test multiple scenarios.

存根:使我们能够替换功能。 这给了我们更多的控制权。 我们可以返回我们想要的任何东西,或者让我们的功能以适合我们测试多个场景的方式工作。

Mocks: They are fake methods, that have pre-programmed behavior and pre-programmed expectations.

嘲讽:它们是伪造的方法,具有预先设定的行为和预先设定的期望。

间谍,存根,模拟 ( Spies, Stubs, Mocks )

We have a basic understanding of what these are. Let's try them out. Create a new file on your project folder; /controllers/app.controller.js.

我们对这些内容有基本的了解。 让我们尝试一下。 在您的项目文件夹中创建一个新文件; /controllers/app.controller.js

间谍 (Spies)

Since we are doing Node testing, its safe to assume that we'll have a function for our endpoints that will look something like this:

由于我们正在进行节点测试,因此可以放心地假设我们将为端点提供一个类似于以下功能的函数:

module.exports = {
  // A func that takes in two parameters `req` and `res` [request, response]
  getIndexPage: (req, res) => {
    res.send("Hey");
  }
}

While testing this we require a function that takes in two parameters for our tests. Create a new file inside the tests folder; /tests/controllers/app.controller.test.js

在测试时,我们需要一个带有两个参数的函数来进行测试。 在tests文件夹中创建一个新文件; /tests/controllers/app.controller.test.js

We can just instantiate req and res to empty objects and use that.

我们可以实例化reqres到空对象并使用它。

const chai = require("chai");
const expect = chai.expect;
// import our getIndexPage function
const indexPage = require("../../controllers/app.controller.js");

describe("getIndexPage", function() {
  it("should return index page", function() {
    let req = {}
    // Have `res` have a send key with a function value coz we use `res.send()` in our func
    let res = {
      send: function() {}
    }

    indexPage.getIndexPage(req, res)
  });
});

This doesn't really give us anything to test or much control over the function. We could use a spy and then make some assertions on the spy. Making assertions on a spy is possible because the spy gives us a dummy function that we can use to track our functions execution.

这实际上并没有给我们任何测试或对该功能的太多控制。 我们可以使用间谍,然后对间谍进行断言。 对间谍进行断言是可能的,因为间谍为我们提供了一个虚拟函数,可用来跟踪函数执行情况。

const chai = require("chai");
const expect = chai.expect;
// import sinon
const sinon = require("sinon");
const indexPage = require("../../controllers/app.controller.js");

describe("getIndexPage", function() {
  it("should return index page", function() {
    let req = {}
    // Have `res` have a send key with a function value coz we use `res.send()` in our func
    let res = {
      send: sinon.spy()
    }

    indexPage.getIndexPage(req, res);
    // let's see what we get on res.send
    console.log(res.send);
  });
});

Now, when we run our tests, which we'll do by running mocha tests/**/*.* (we have to tell mocha where our tests live); we can see what res.send returns. Its basically a list of all the methods we could call to make assertions for our tests.

现在,当我们运行测试时,我们将通过运行mocha tests/**/*.* (必须告诉mocha我们的测试在哪里)来完成; 我们可以看到res.send返回什么。 它基本上是我们可以调用的用于进行测试断言的所有方法的列表。

Let's go ahead and make some of these assertions:

让我们继续进行一些断言:

  • We'll expect that our function res.send is called once

    我们希望我们的函数res.send被调用一次
  • We'll expect that we get an argument Hey on the firstCall

    我们希望在firstCall上收到一个参数Hey
const chai = require("chai");
const expect = chai.expect;
// import sinon
const sinon = require("sinon");
const indexPage = require("../../controllers/app.controller.js");

describe("getIndexPage", function() {
  it("should send hey", function() {
    let req = {}
    // Have `res` have a send key with a function value coz we use `res.send()` in our func
    let res = {
      // replace empty function with a spy
      send: sinon.spy()
    }

    indexPage.getIndexPage(req, res);
    // let's see what we get on res.send
    console.log(res.send);
    // `res.send` called once
    expect(res.send.calledOnce).to.be.true;
    // expect to get argument `bla` on first call
    expect(res.send.firstCall.args[0]).to.equal("bla");
  });
});

When we run this, notice we get a failing test. This is because we expect to get an argument bla instead of Hey. We can go back to our code and replace bla with Hey and run our tests again. This way, they pass. I put this in here because sometimes its worthwhile to make your tests fail first so that you make certain that you aren't experiencing false positives. From here on feel free to fail the next tests on purpose and then make them pass, if you haven't been doing that already.

运行此命令时,请注意测试失败。 这是因为我们希望得到bla而不是Hey的争论。 我们可以回到我们的代码,并用Hey替换bla并再次运行我们的测试。 这样,他们通过了。 我将其放在这里是因为有时值得让您的测试首先失败,以便您确定自己没有误报。 从这里开始,如果您还没有这样做的话,可以放心地通过下一个测试,然后使其通过。

What if we had an already existing function and we just want to spy on that function? We can simulate this scenario by defining a simple function like so:

如果我们已有一个功能,而只想监视该功能怎么办? 我们可以通过定义一个简单的函数来模拟这种情况:

const chai = require("chai");
const expect = chai.expect;
// import sinon
const sinon = require("sinon");
const indexPage = require("../../controllers/app.controller.js");

const user = {
  addUser: (name) => {
    this.name = name;
  }
}

describe("AppController", function()  {
  describe("getIndexPage", function() {
    it("should send hey", function() {
      let req = {}
      // Have `res` have a send key with a function value coz we use `res.send()` in our func
      let res = {
        // replace empty function with a spy
        send: sinon.spy()
      }

      indexPage.getIndexPage(req, res);
      // let's see what we get on res.send
      // console.log(res.send);
      // `res.send` called once
      expect(res.send.calledOnce).to.be.true;
      expect(res.send.firstCall.args[0]).to.equal("Hey");
    });
  });
});
describe("User", function() {
  describe("addUser", function() {
    it("should add a user", function() {
      sinon.spy(user, "addUser");

      // lets log `addUser` and see what we get
      console.log(user.addUser);
    });
  });
});

From our console.log you can see, we get all the watch functionality on our already existing function. We can go ahead and make some assertions on this function just like we did before.

您可以从console.log中看到,我们在现有功能上获得了所有监视功能。 我们可以像以前一样继续对此功能进行断言。

const chai = require("chai");
const expect = chai.expect;
// import sinon
const sinon = require("sinon");
const indexPage = require("../../controllers/app.controller.js");

const user = {
  addUser: (name) => {
    this.name = name;
  }
}

...

describe("User", function() {
  describe("addUser", function() {
    it("should add a user", function() {
      sinon.spy(user, "addUser");
      user.addUser('John Doe');

      // lets log `addUser` and see what we get
      console.log(user.addUser);
      expect(user.addUser.calledOnce).to.be.true;
    });
  });
});

So far, we know how to use spies; both to create dummy functions and to wrap already existing functions so that we are able to watch and test our functions. You'll find that most of the time we'll probably not use spies but they are pretty useful to test whether callbacks have been called and how many times they were called during our code execution. Spies are the simplest to use in SinonJS and most functionality is built on top of them. They are a pretty good starting point with SinonJS.

到目前为止,我们知道如何使用间谍。 既可以创建虚拟函数,也可以包装已经存在的函数,以便我们能够监视和测试我们的函数。 您会发现大多数时候我们可能不会使用间谍,但是它们在测试代码执行过程中对是否已调用回调以及调用多少次非常有用。 间谍是在SinonJS中使用最简单的工具,大多数功能都建立在它们之上。 它们是SinonJS的一个很好的起点。

存根 (Stubs)

Stubs are really great. This is because; they have all the functionality of spies but unlike spies they replace the whole function. This means that with spies the function runs as is but with a stub you are replacing said function. This helps in scenarios where we need to test:

存根真的很棒。 这是因为; 它们具有间谍的所有功能,但与间谍不同,它们取代了整个功能。 这意味着使用间谍功能可以按原样运行,但是使用存根即可替换该功能。 这在需要测试的方案中有帮助:

  • External calls which make tests slow and difficult to write (e.g HTTP calls/ DB calls)

    外部调用使测试变慢且难以编写(例如HTTP调用/ DB调用)
  • Triggering different outcomes for a piece of code (e.g. what happens if an error is thrown/ if it passes)

    触发一段代码的不同结果(例如,如果引发错误/通过则发生错误)

Enough talk let's dig into stubs:

足够多的讨论让我们深入研究存根:

We'll add a function to our app controller. Just to broaden the scope of things to test. In our /controllers/app.controller.js we can add this code.

我们将向我们的应用程序控制器添加一个功能。 只是为了拓宽测试范围。 在我们的/controllers/app.controller.js我们可以添加此代码。

module.exports = {
  // A func that takes in two parameters `req` and `res` [request, response]
  getIndexPage: (req, res) => {
    if (req.user.isLoggedIn()) {
      return res.send("Hey");
    }
    res.send("Ooops. You need to log in to access this page");
  }
}

Now, in our getIndexPage function we check to see if a user isLoggedIn to send the message Hey otherwise we send another message, Ooops. You need to log in to access this page.

现在,在我们的getIndexPage函数中,我们检查用户isLoggedIn是否发送消息Hey否则,我们发送另一条消息Ooops. You need to log in to access this page Ooops. You need to log in to access this page

isLoggedIn in this case is a function that does some checks to see whether current user is logged in. It could be that it checks the users' jwt tokens or make direct calls to the database, we really don't have to know what the function does exactly. We'll just imagine its some expensive operation happening that either returns true when the user is logged in or false otherwise.

在这种情况下, isLoggedIn是一个函数,它将进行一些检查以查看当前用户是否已登录。可能是它检查了用户的jwt tokens或直接调用了数据库,我们真的不必知道该函数是什么恰好。 我们只是想像一下它发生的一些昂贵操作,当用户登录时返回true,否则返回false。

Let's test it. In our test file we can replace what we had with this:

让我们测试一下。 在我们的测试文件中,我们可以用以下内容代替已有的内容:

const chai = require("chai");
const expect = chai.expect;
// import sinon
const sinon = require("sinon");
const indexPage = require("../../controllers/app.controller.js");

describe("AppController", function()  {
  describe("getIndexPage", function() {
    it("should send hey when user is logged in", function() {
      // instantiate a user object with an empty isLoggedIn function
      let user = {
        isLoggedIn: function(){}
      }

      // Stub isLoggedIn function and make it return true always
      const isLoggedInStub = sinon.stub(user, "isLoggedIn").returns(true);

      // pass user into the req object
      let req = {
        user: user
      }

      // Have `res` have a send key with a function value coz we use `res.send()` in our func
      let res = {
        // replace empty function with a spy
        send: sinon.spy()
      }

      indexPage.getIndexPage(req, res);
      // let's see what we get on res.send
      // console.log(res.send);
      // `res.send` called once
      expect(res.send.calledOnce).to.be.true;
      expect(res.send.firstCall.args[0]).to.equal("Hey");

      // assert that the stub is logged in at least once
      expect(isLoggedInStub.calledOnce).to.be.true;
    });
  });
});

What we did is stub out the isLoggedIn function and made it return true always for this case. The stub replaces isLoggedIn and now we can test scenarios where the user is logged in. In our case when user us logged in we expect to see the message Hey. If we run our tests now mocha tests/**/*.*, they should pass. We can also now test when the user is logged out by making our stub return false.

我们所做的是将isLoggedIn函数存根,并在这种情况下始终使其返回true 。 存根替换了isLoggedIn ,现在我们可以测试用户登录的场景。在我们这种情况下,当用户登录时,我们希望看到消息Hey 。 如果我们现在运行测试,则mocha tests/**/*.* ,它们应该通过。 现在,我们还可以通过使存根返回false来测试何时注销用户。

...

describe("AppController", function()  {
  describe("getIndexPage", function() {
    it("should send hey when user is logged in", function() {
      ...
    });

    it("should send something else when user is NOT logged in", function() {
      // instantiate a user object with an empty isLoggedIn function
      let user = {
        isLoggedIn: function(){}
      }

      // Stub isLoggedIn function and make it return false always
      const isLoggedInStub = sinon.stub(user, "isLoggedIn").returns(false);

      // pass user into the req object
      let req = {
        user: user
      }

      // Have `res` have a send key with a function value coz we use `res.send()` in our func
      let res = {
        // replace empty function with a spy
        send: sinon.spy()
      }

      indexPage.getIndexPage(req, res);
      // let's see what we get on res.send
      // console.log(res.send);
      // `res.send` called once
      expect(res.send.calledOnce).to.be.true;
      expect(res.send.firstCall.args[0]).to.equal("Ooops. You need to log in to access this page");

      // assert that the stub is logged in at least once
      expect(isLoggedInStub.calledOnce).to.be.true;
    })
  });
});

Thats how stubs work in a nutshell. You can go crazy with them and throw specific errors and such. Check them out on the docs. Mocks is up next!!

那就是存根简而言之的工作方式。 您可以对它们发疯,并抛出特定的错误等。 在文档上查看它们。 嘲笑是下一步!

cks (Mocks)

With mocks we can specify how we want something to work and use mock.verify() to make sure it works. This means less and cleaner code. With our already existing tests we could:

通过模拟,我们可以指定我们希望某些东西如何工作,并使用mock.verify()来确保它能正常工作。 这意味着更少和更干净的代码。 使用我们已经存在的测试,我们可以:

  • mock our res object

    模拟我们的res对象
  • expect send to be called once with the argument Hey

    期望send一次带有参数Hey的调用
  • then call mock.verify()

    然后调用mock.verify()

Just like this:

像这样:

const chai = require("chai");
const expect = chai.expect;
const sinon = require("sinon");
const indexPage = require("../../controllers/app.controller.js");

describe("AppController", function()  {
  describe("getIndexPage", function() {
    it("should send hey when user is logged in", function() {
      // instantiate a user object with an empty isLoggedIn function
      let user = {
        isLoggedIn: function(){}
      }

      // Stub isLoggedIn function and make it return true always
      const isLoggedInStub = sinon.stub(user, "isLoggedIn").returns(true);

      // pass user into the req object
      let req = {
        user: user
      }

      // Have `res` have a send key with a function value coz we use `res.send()` in our func
      let res = {
        send: function(){}
      }

      // mock res
      const mock = sinon.mock(res);
      // build how we expect it t work
      mock.expects("send").once().withExactArgs("Hey");

      indexPage.getIndexPage(req, res);
      expect(isLoggedInStub.calledOnce).to.be.true;

      // verify that mock works as expected
      mock.verify();
    });
  });
});

测试异步代码 ( Testing Async Code )

回呼 (Callbacks)

JS is inherently asynchronous. So testing async code happens pretty frequently. Let's write some async code then try testing it. It should be pretty easy.

JS本质上是异步的。 因此,测试异步代码非常频繁。 让我们编写一些异步代码,然后尝试对其进行测试。 应该很容易。

Let's create a basic async function and test it. Create a new file tests/asyncFunc.test.js

让我们创建一个基本的异步函数并对其进行测试。 创建一个新文件tests/asyncFunc.test.js

const chai = require("chai");
const expect = chai.expect;

// This is just an async func that takes in a bool
// and calls a callback that returns a some message
// depending on the bool value
function someMadeUpAyncFunc(boolValue, cb) {
  setTimeout(function() {
    cb(boolValue ? "You get a sweet :)" : "You get nothing!!")
  }, 0);
}

// Added the `only` tag to have only this set of tests to run
describe.only("AsyncTest", function()  {
  it("should return `You get a sweet :)` if `true` is passed in", function() {
    someMadeUpAyncFunc(true, function(sweetCheck){
      expect(sweetCheck).to.equal("You get a sweet :)");
    });
  });

  it("should return `You get nothing!!` if `false` is passed in", function() {
    someMadeUpAyncFunc(false, function(sweetCheck){
      // Let's fail it on purpose just to see what happens
      expect(sweetCheck).to.equal("You get a sweet :)");
    });
  });
});

Okay, this is weird. All our tests are passing even though we know that the last test should fail. Bummer! We know why this is happening though. Think about it, Mocha is expecting an exception to be thrown but this isn't happening because the tests are running synchronously even though our function takes some time to run. So, our tests finish executing before our function gets the chance to complete. What we need, is a way to tell our tests that we are expecting something. The way we can do this is by; passing done key word in our it function. This alerts Mocha that we have to wait for done to be called. So is we add done now to our code we can see our failing test now.

好吧,这很奇怪。 即使我们知道最后一个测试应该失败,我们所有的测试都通过了。 mm! 我们知道为什么会这样。 仔细考虑一下,Mocha预计会引发异常,但这不会发生,因为即使我们的函数需要一些时间才能运行,测试仍会同步运行。 因此,在我们的函数有机会完成之前,我们的测试完成了执行。 我们需要的是一种告诉测试我们期望的方法。 我们做到这一点的方法是: 在我们的it函数中传递done关键字。 这会提醒Mocha我们必须等待done被调用。 因此,我们现在将done添加到我们的代码中,现在我们可以看到失败的测试。

const chai = require("chai");
const expect = chai.expect;

// This is just an async func that takes in a bool
// and calls a callback that returns a some message
// depending on the bool value
function someMadeUpAyncFunc(boolValue, cb) {
  setTimeout(function() {
    cb(boolValue ? "You get a sweet :)" : "You get nothing!!")
  }, 0);
}

// Added the `only` tag to have only this set of tests to run
describe.only("AsyncTest", function()  {
  it("should return `You get a sweet :)` if `true` is passed in", function(done) {
    someMadeUpAyncFunc(true, function(sweetCheck){
      expect(sweetCheck).to.equal("You get a sweet :)");
      done();
    });
  });

  it("should return `You get nothing!!` if `false` is passed in", function(done) {
    someMadeUpAyncFunc(false, function(sweetCheck){
      // Let's fail it on purpose just to see what happens
      expect(sweetCheck).to.equal("You get a sweet :)");
      done();
    });
  });
});

When we run mocha tests/**/*.* we now see our failing test!! You could go back and now fix it. We are sure that our tests are not giving us false positives now.

当我们运行mocha tests/**/*.*我们现在看到失败的测试! 您可以返回,现在修复它。 我们确信我们的测试现在不会给我们带来误报。

承诺 (Promises)

Let's use promises for our async functions. Testing code with promises is a bit different than using callbacks. We'll need to install chai-as-promised to allow us to test our promises using Chai.

让我们对异步函数使用promises 。 使用promise测试代码与使用回调有点不同。 我们将需要安装chai-as-promised promise,以允许我们使用Chai来检验我们的承诺。

> npm install --save-dev chai-as-promised

We'll just use our sweetCheck function. We'll change it up a bit and use a promise instead of the callback.

我们将只使用sweetCheck函数。 我们将对其进行一些更改,并使用promise代替回调。

const chai = require("chai");
const expect = chai.expect;
chai.use(require("chai-as-promised"));

// This is just an async func that takes in a bool
// and that returns a promise
function someMadeUpAyncFunc(boolValue, cb) {
  return new Promise(function(resolve){
    setTimeout(function() {
      resolve(boolValue ? "You get a sweet :)" : "You get nothing!!")
    }, 0);
  })
}

// Added the `only` tag to have only this set of tests to run
describe.only("AsyncTest", function()  {
  it("should return `You get a sweet :)` if `true` is passed in", function() {
    return expect(someMadeUpAyncFunc(true)).to.eventually.equal("You get a sweet :)");
  });

  it("should return `You get nothing!!` if `false` is passed in", function() {
    return expect(someMadeUpAyncFunc(false)).to.eventually.equal("You get nothing!!");
  });
});

We are using some new assertions. These are provided by chai-as-promised. You can read up on and experiment with more of these assertions here. Notice we also do not need to use done in this case. All we need to do is return our promise and Mocha will handle it by itself.

我们正在使用一些新的断言。 这些由chai-as-promised提供。 您可以在此处继续阅读并尝试更多这些断言。 注意,在这种情况下,我们也不需要使用done 。 我们需要做的就是兑现我们的诺言,摩卡咖啡将自己履行诺言。

结论 ( Conclusion )

Phew! We now have all this knowledge on some useful tools we can use to test our Node Apps with. What next? Create your own app from scratch and test it. You will definitely encounter a lot more scenarios that we haven't covered yet. Feel free to post up all those questions on the comment section. If you'd like to go over what we have done here on github you could use this repo to see all the different code we've used so far.

! 现在,我们已经掌握了一些有用的工具,可以用来测试Node Apps。 接下来是什么? 从头开始创建自己的应用程序并进行测试。 您肯定会遇到很多我们尚未涉及的场景。 随时在评论部分上发布所有这些问题。 如果您想了解我们在github上所做的工作,则可以使用此存储查看到目前为止我们使用的所有不同代码。

Happy Testing!!

测试愉快!

翻译自: https://scotch.io/tutorials/how-to-test-nodejs-apps-using-mocha-chai-and-sinonjs

mocha测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值