GVKun编程网logo

Using Mocks for Testing in JavaScript with Sinon.js

5

在本文中,我们将为您详细介绍UsingMocksforTestinginJavaScriptwithSinon.js的相关知识,此外,我们还会提供一些关于*something*if*expressio

在本文中,我们将为您详细介绍Using Mocks for Testing in JavaScript with Sinon.js的相关知识,此外,我们还会提供一些关于* something * if * expression * JavaScript in JavaScript(FF)、Beginning JavaScript with DOM Scripting and Ajax 第二版免积分下载、Beginning JavaScript with DOM Scripting and Ajax 第二版电子书分享、Calling WebServices using Javascript的有用信息。

本文目录一览:

Using Mocks for Testing in JavaScript with Sinon.js

Using Mocks for Testing in JavaScript with Sinon.js

http://stackabuse.com/using-mocks-for-testing-in-javascript-with-sinon-js/


Introduction

Test "mocks" are objects that replace real objects while simulating their functions. A mock also has expectations about how the functions being tested will be used.

In some unit test cases we may want to combine the functionality of spies, to observe a method''s behavior under call, and that of stubs, to replace a method''s functionality, in ensuring that we do not make an actual function call but are still able to monitor the behavior of our target function accordingly. In such a case, we can use mocks.

In this article, we will seek to understand what mocks are and how to use them in unit tests. We''ll then get hands-on experience with Sinon.js to mock an HTTP request.

This article is the third of our series on unit testing techniques with Sinon.js. We recommend that you read our previous articles on this topic as well:

  • Using Stubs for Testing in JavaScript with Sinon.js
  • Using Spies for Testing in JavaScript with Sinon.js

What are Mocks?

Mocks combine the functionality of both spies and stubs, which means that they replace the target function but at the same time provide us with the ability to observe how the function was called.

Furthermore, mocks have built-in assertions called expectations. You define the expectations of how your mocked function will be used upfront. If your mock did not satisfy its expectations, your test will fail.

For example, let''s consider a function that communicates with a database to save a contact''s details. With a mock, instead of a real database, our function will hit a fake database object. We can determine what kind of response it will give. We''ll also state how many times the database should be called and the arguments it should be called with.

Finally, as part of the test, we verify that our database mock was called the exact amount of times we expected. We also check that it got called with only the arguments our function supposed to provide it.

Having seen what mocks are, let us now look at situations where we can employ them.

Why Use Mocks?

Mocks are useful when validating how an external dependency is used within a function. Use mocks when you are in interested in:

  • Confirming that your external dependency is used at all
  • Verifying that your external dependency is used correctly
  • Ensuring that your function can handle different responses from external dependencies.

Imagine that you are testing a function that speaks with a third party API to get some user data. To make requests to the external API, you''ll need to make a few calls to authenticate first. It''s already becoming inconvenient to use the real API in tests. Additionally, you might not always have an internet connection to access the API while running your tests.

With a mock, we will return fake responses. We can now quickly test that our function behaves correctly when given the fake data in a particular format. We''ll also know that our function made requests to the API with the right parameters.

Let''s now look at how we can use Sinon.js to create mocks.

Using Sinon.js to Create a Mock

We''ll use Sinon.js to mock a response from a JSON API that retrieves a list of photos in an album. In addition to Sinon.js, we will be using Mocha and Chai to setup and run the tests. You can read our guide our guide to learn more about them before continuing.

Setup

Create a directory called SinonMock and move into it:

$ mkdir SinonMock
$ cd SinonMock

We will then use NPM to initialize a project to track the project files we create:

$ npm init -y

Next, we''ll install Mocha and Chai as testing dependencies to run our tests, along with Sinon.js:

$ npm i mocha chai sinon --save-dev

Having completed our setup, let''s mock an HTTP request.

Mocking an HTTP Call with Sinon.js

In our previous article on test spies, we spied on an HTTP request to the photo album API. We''ll continue with that example for this article.

Create a file in the root of the SinonMock directory and call it index.js:

$ touch index.js

In the file created, enter the following code:

const request = require(''request'');

module.exports = {
    getAlbumById: async function(id) {
        const requestUrl = `https://jsonplaceholder.typicode.com/albums/${id}/photos?_limit=3`;
        return new Promise((resolve, reject) => {
            request.get(requestUrl, (err, res, body) => {
                if (err) {
                    return reject(err);
                }
                resolve(JSON.parse(body));
            });
        });
    }
};

To recap, getAlbumById() is a function which calls a JSON API that returns a list of photos. We provide an album ID as the function argument. We have previously explored stubbing and spying on the request.get() method.

Now, we will mock the request object and check if the get() method is called once, as required, and verify if it received the correct arguments. We''ll then verify that our function has the correct properties based on what was returned from our mock.

Create another file at the root of the SinonMock directory and call it index.test.js:

$ touch index.test.js

Open the index.test.js file with an editor and enter the following code:

const expect = require(''chai'').expect;
const request = require(''request'');
const sinon = require(''sinon'');
const index = require(''./index'');

describe(''with mock: getPhotosByAlbumId'', () => {
    it(''should getPhotosByAlbumId'', (done) => {
        let requestMock = sinon.mock(request);
        const myPhotos = [{
            "albumId": 1,
            "id": 1,
            "title": "accusamus beatae ad facilis cum similique qui sunt",
            "url": "https://via.placeholder.com/600/92c952",
            "thumbnailUrl": "https://via.placeholder.com/150/92c952"
        },
        {
            "albumId": 1,
            "id": 2,
            "title": "reprehenderit est deserunt velit ipsam",
            "url": "https://via.placeholder.com/600/771796",
            "thumbnailUrl": "https://via.placeholder.com/150/771796"
        },
        {
            "albumId": 1,
            "id": 3,
            "title": "officia porro iure quia iusto qui ipsa ut modi",
            "url": "https://via.placeholder.com/600/24f355",
            "thumbnailUrl": "https://via.placeholder.com/150/24f355"
        }];

        requestMock.expects("get")
            .once()
            .withArgs(''https://jsonplaceholder.typicode.com/albums/2/photos?_limit=3'')
            .yields(null, null, JSON.stringify(myPhotos));

        index.getAlbumById(2).then((photos) => {
            expect(photos.length).to.equal(3);
            photos.forEach((photo) => {
                expect(photo).to.have.property(''id'');
                expect(photo).to.have.property(''title'');
                expect(photo).to.have.property(''url'');
            });

            requestMock.verify();
            requestMock.restore();
            done();
        });
    });
});

In our test case above, we first create a mock of the request object using sinon.mock() and name it requestMock. The requestMock object has the functions of the request object but the functions do nothing by default.

After supplying some fixed photo data, we override the original get() method of the request object by using Sinon.js'' mock API''s expect() method.

The expect() method takes in a single argument, which is the method of the mocked object we anticipate will be used.

The once() method asserts that our expectation is called once. In this case the get() method of the request object will be called exactly one time.

The withArgs() method asserts that we expect the get() method to be called with the array of arguments we supply to it. In our case the URL of the API.

The yields() method puts data into the callback that our mock object accepts. In this case, our error and response are both null but our body has a JSON response.

After this setup, we then call our getAlbumById() method and check if the photos returned to have the correct properties.

Notice the verify() call of the requestMock object to confirm that our expectations were met. If expectations fail, the test will throw an exception. We then call the restore() method to discard the mock created by our test and restore the original request object.

When you run this test, you should get the following result:

$ mocha index.test.js

with mock: getPhotosByAlbumId
     should getPhotosByAlbumId


  1 passing (13ms)

  Done in 0.72s.

To confirm the behavior of our mock, let''s see if the expectations fail if we change the URL we communicate with. In your index.js file, change:

const requestUrl = `https://jsonplaceholder.typicode.com/albums/${id}/photos?_limit=3`;

To:

const requestUrl = `https://example.com`;

Now run the tests once more:

$ mocha index.test.js

Since we changed the input to the get() method, the URL argument no longer matches what''s in our test. We''ll get this output when we run the test:

> mocha index.test.js



  with mock: getPhotosByAlbumId
(node:85434) UnhandledPromiseRejectionWarning: ExpectationError: Unexpected call: get(https://example.com, function () {})
    Expected get(https://jsonplaceholder.typicode.com/albums/2/photos?_limit=3[, ...]) once (never called)

Great! We''re pretty certain that our mocks will guarantee that our function behaves as we expect!

By using a mock, we have been able to get the benefits of both spies and stubs. We were able to check that our function was called exactly once, and with the correct arguments, a benefit provided us by spies. We were also able to stub the request so that we were not making an actual HTTP call to the API, which ensured that our test ran quickly.

Conclusion

Mocks in unit testing combine the functionality of both spies and stubs by replacing functions like stubs and at the same time providing us with means of observing the functions to check how they were called, the functionality provided us by spies. Mocks then give us the benefit of verifying how our function was used in a test.

In this article, we introduced the concept of mocking in unit testing, and saw how we could mock an HTTP call. To learn more about Sinon.js mocks, you can review the official documentation of the mocks API.

* something * if * expression * JavaScript in JavaScript(FF)

* something * if * expression * JavaScript in JavaScript(FF)

我看到一些例子表明,Firefox支持某种 JavaScript语法,如* * * * * * * * *.

作为我正在谈论的例子,请参阅this MDN article,其中包含以下示例:

var evens = [i for each (i in range(0,21)) if (i % 2 == 0)];

我的问题是:

用什么名字来描述这种语法?我主要想知道这一点,所以我可以把谷歌和更多的阅读.我已经尝试了谷歌最好的我可以想出来,但没有能够把正确的术语在一起,以获得有用的结果.

这个语法是否存在于数组解析之外的其他地方?我觉得我已经看到在数组之外使用的其他例子(例如上面的例子),但我不确定.

在哪里可以阅读有关此语法的更多信息?

除Firefox之外,其他任何浏览器都支持这种浏览器?

这是ES5中的这个功能还是计划用于ES和谐?

解决方法

正如其他人所说,这被称为“阵列理解”,它是为ECMAScript Harmony建议的许多功能之一:

http://wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions

然而,正如几乎每一个和谐的“功能”,我不认为有没有真正的概念是否将真正包括在最终版本.您可以在Firefox中使用它作为“JavaScript 1.7”的一部分(真正仅适用于基于Mozilla的东西的模糊的“标准”规范);但是,您最好避免使用特定于FF的语法,特别是在其他浏览器中会导致语法错误.

您可以通过Google搜索“Array Comprehensions”来阅读更多信息,但正如我所提到的,由于它具有Mozilla特有的性质,因此它不是一个非常有用的工具.

您可以使用ES5中引入的reduce()Array方法实现类似的效果,而不需要更多的代码:

//JavaScript has no "range" function,so let's make one
var range = function (begin,length) { 
    var i,ret = [];
    for (i = begin; i < begin + length; i++) {
        ret.push(i);
    }
    return ret;
};

var evens = range(0,21).reduce(function (arr,cur) { 
    if (cur % 2 === 0) arr.push(cur);
    return arr; 
},[]);

与您正在寻找的内容相比,这可能有点冗长(甚至记住我们必须创建一个range()函数).但它是一个相对紧凑的解决方案,不需要大量的“设置”,主要解决问题:从一个数组过滤元素以形成第二个数组.

我能够把它减少到一个单行,但是变得有点不健康,所以我决定建议两行版本.如果你对一线感兴趣,这里是:

//Don't forget to define "range()"
var evens = range(0,cur) { 
    return (cur % 2 === 0) ? (arr.push(cur) && arr) : arr; 
},[]);

再次,这是ES5代码.如果您希望它在旧版浏览器中工作,那么您需要提供一个垫片来为Array.reduce()提供支持. MDN有一个:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce

更新:

看起来我应该使用filter()而不是reduce().使代码更清洁.感谢OP建议!

var evens = range(0,21).filter(function (cur) { return cur % 2 === 0; });

再次,filter()是ES5,所以你需要一个垫片,以确保它在旧的浏览器上正常工作.

Beginning JavaScript with DOM Scripting and Ajax 第二版免积分下载

Beginning JavaScript with DOM Scripting and Ajax 第二版免积分下载

Beginning JavaScript with DOM Scripting and Ajax

Beginning JavaScript with DOM Scripting and Ajax, 2nd Edition

本书介绍

Beginning JavaScript with DOM Scripting and Ajax 是现代 javascript 编程的一个基本资源。这个完全更新的第二版涵盖了所有您需要了解的内容,以提高 javascript 开发的速度,并从 basics 向网页添加动态增强,同时关注客户端 javascript,您还将学习如何使用浏览器对象模型,文档对象模型 (Dom),以及如何使用。XML 和 json 以及与服务端脚本 (如 php) 的通信。了解如何:

按照现代编码实践构建良好的 javascript 语法

使用 javascript 与服务器通信并检索数据

动态地操作标记,验证表单并处理图像

使用浏览器内的功能调试应用程序

JavaScript 是 Web 上最重要的技术之一。它为您的网页提供了添加动态功能的手段,并充当 Ajax 风格 Web 开发的骨干。使用 dom 脚本和 Ajax 开始使用 javascript 将使您不再是 javascript 新手,可以自由使用这一重要技术 -- 从今天开始您的 javascript 之旅!

你会学到什么

什么函数、变量、事件和对象以及如何使用它们。

如何在 javascript 被关闭的情况下构建一个仍然有效的站点。如何使用代码访问和更新部分页面。

如何使用 javascript 与服务器通信并检索数据。

如何使用 javascript 进行表单验证和用户反馈。

如何使用第三方库 (如 jQuery)。

本书适用于谁

Beginning JavaScript with DOM Scripting and Ajax  是为了那些对 html 和 CSS 有很好的掌握,但想要在他们的技能中添加 javascript 的人。如果您想学习一些基本的编程概念,有经验但需要帮助更新您的技能,或者您来自另一种语言,使用 dom 脚本和 Ajax 开始使用 javascript 可能会有所帮助。

目录

Chapter 1. Getting Started with JavaScript

Chapter 2. Data and Decisions

Chapter 3. From DHTML to DOM Scripting

Chapter 4. HTML and JavaScript

Chapter 5. Presentation and Behavior (CSS and Event Handling)

Chapter 6. Common Uses of JavaScript: Images and Windows

Chapter 7. JavaScript and User Interaction: Navigation and Forms

Chapter 8. Back-End Interaction with Ajax and Node.js

Chapter 9. Data Validation Techniques

Chapter 10. Modern JavaScript Case Study: A Dynamic Gallery

Chapter 11. Using Third-Party JavaScript

Appendix A. Debugging JavaScript

下载地址:Beginning JavaScript with DOM Scripting and Ajax.pdf

更多免费电子书,请查看我的简书主页及相关专题

Beginning JavaScript with DOM Scripting and Ajax 第二版电子书分享

Beginning JavaScript with DOM Scripting and Ajax 第二版电子书分享

Beginning JavaScript with DOM Scripting and Ajax

Beginning JavaScript with DOM Scripting and Ajax, 2nd Edition

本书介绍

Beginning JavaScript with DOM Scripting and Ajax 是现代javascript编程的一个基本资源。这个完全更新的第二版涵盖了所有您需要了解的内容,以提高javascript开发的速度,并从basics向网页添加动态增强,同时关注客户端javascript,您还将学习如何使用浏览器对象模型,文档对象模型(Dom),以及如何使用。XML和json以及与服务端脚本(如php)的通信。了解如何:

按照现代编码实践构建良好的javascript语法

使用javascript与服务器通信并检索数据

动态地操作标记,验证表单并处理图像

使用浏览器内的功能调试应用程序

JavaScript是Web上最重要的技术之一。它为您的网页提供了添加动态功能的手段,并充当Ajax风格Web开发的骨干。使用dom脚本和Ajax开始使用javascript将使您不再是javascript新手,可以自由使用这一重要技术--从今天开始您的javascript之旅!

你会学到什么

什么函数、变量、事件和对象以及如何使用它们。

如何在javascript被关闭的情况下构建一个仍然有效的站点。如何使用代码访问和更新部分页面。

如何使用javascript与服务器通信并检索数据。

如何使用javascript进行表单验证和用户反馈。

如何使用第三方库(如jQuery)。

本书适用于谁

Beginning JavaScript with DOM Scripting and Ajax  是为了那些对html和CSS有很好的掌握,但想要在他们的技能中添加javascript的人。如果您想学习一些基本的编程概念,有经验但需要帮助更新您的技能,或者您来自另一种语言,使用dom脚本和Ajax开始使用javascript可能会有所帮助。

目录

Chapter 1. Getting Started with JavaScript

Chapter 2. Data and Decisions

Chapter 3. From DHTML to DOM Scripting

Chapter 4. HTML and JavaScript

Chapter 5. Presentation and Behavior (CSS and Event Handling)

Chapter 6. Common Uses of JavaScript: Images and Windows

Chapter 7. JavaScript and User Interaction: Navigation and Forms

Chapter 8. Back-End Interaction with Ajax and Node.js

Chapter 9. Data Validation Techniques

Chapter 10. Modern JavaScript Case Study: A Dynamic Gallery

Chapter 11. Using Third-Party JavaScript

Appendix A. Debugging JavaScript

下载地址:Beginning JavaScript with DOM Scripting and Ajax.pdf

更多免费电子书,请查看我的简书主页及相关专题

Calling WebServices using Javascript

Calling WebServices using Javascript

If you are using Microsoft IE 5 or later,you can use the behavior/HTML-Component "WebService" to access a Web service. The "WebService" behavior communicates with Web services over HTTP using Simple Object Access Protocol (SOAP).

To use the "WebService" behavior,you must attach it to an element using the STYLE attribute,as follows:

<DIV ID="GiveItAName"
></DIV>

A complete example taken from the Microsoft Web site is as follows:

<html>
<head>
<script language="JavaScript">
var iCallID;

function init()
{
service.useService
("
http://myserver.com/services/myservice.asmx?WSDL",
                   "servicename");
}

function onmyresult()
{
   if ((event.result.error)&&(iCallID==event.result.id))
   {
      var xfaultcode = event.result.errorDetail.code;
      var xfaultstring = event.result.errorDetail.string;
      var xfaultsoap = event.result.errorDetail.raw;

      // Add code to output error information here
      alert("Error ");
   }
   else
   {
      service.innerHTML= "The method returned the result: "
                         + event.result.value;
   }
}
</script>
</HEAD>
<body onload="init();">
<BR>
Enter a Value <input type=''text'' id=''param1''>
<BR>
<button onclick=''iCallID = service.servicename.callService
("ProcedureName",param1.value);''>Call A Web Method</button>
<div id="service"
    
     onresult="onmyresult();">
</div>
</body>
</html>

source: http://weblogs.asp.net/Varad/archive/2004/06/14/155671.aspx

posted on 2004-06-15 18:47 ccBoy 评论(3) 收藏

评论

# re: Calling WebServices using Javascript 2004-06-15 21:15 hBifTs

呵呵,是的,以前也看到过:)

# re: Calling WebServices using Javascript 2004-06-16 20:49 ccBoy

其实这篇更好
Remote Scripting in a .NET World
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting11122001.asp

Scripting Web Services
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting03132000.asp  target="_new" href="http:>  target="_new" href="http:>

关于Using Mocks for Testing in JavaScript with Sinon.js的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于* something * if * expression * JavaScript in JavaScript(FF)、Beginning JavaScript with DOM Scripting and Ajax 第二版免积分下载、Beginning JavaScript with DOM Scripting and Ajax 第二版电子书分享、Calling WebServices using Javascript等相关知识的信息别忘了在本站进行查找喔。

本文标签: