单元测试:Q.js& Jasmine.js [英] Unit-Testing: Q.js & Jasmine.js

查看:111
本文介绍了单元测试:Q.js& Jasmine.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将我的库表单jQuery移植到Q.js,同时将我的单元测试从QUnit重新编写到Jasmine.js,现在面临一些问题:

I ported my library form jQuery to Q.js and at the same time re-wrote my unit-test from QUnit to Jasmine.js and now facing some issue:


  • 由于所有promise对象都被解析为async(setTimeout(func,0)),我必须使用runs和waitsFor编写不那么好的单元测试。

  • jasmine.Clock.useMockapproch无效(两周前租用)

所以我的问题是如何测试我的库使用Q.js与Jasmine.js?

So my question is how to test my library that uses Q.js with Jasmine.js?

更新1:
您可以找到我的单位测试这里。请参阅测试'该工具包的检索方法允许单个记录的延迟该库用于Dynamics CRM 2011环境中的CRUD操作。

Update 1: You can find my unit-tests here. See test "'The "Retrieve" method of the kit allows the laoding of single record'" The library is used for CRUD operations in context of Dynamics CRM 2011.

更新2:
似乎setTimeout不是我唯一的问题。 Q.js将使用setImmediate或MessageChannel或setTimeout来解析异步操作。

Update 2: It seems that the setTimeout is not my only "problem". Q.js will use "setImmediate" or "MessageChannel" or "setTimeout" for resolving the async operation.

推荐答案

如果你是单元测试,你不应该为时钟烦恼。

If you are unit-testing you should not bother about the clock.

假设我们有类似的东西:

Suppose we have something like this:

var obj = {
  functionToTest: function () {
    callServer().then(function () {
      //success
    }, function () {
      //error
    })
  }
}

要测试它,我们需要修改时钟。避免它的一个选择是修改超时以同步解析函数。

To test it we would need to modify the clock. One option to avoid it is to modify timeout to resolve the functions syncronously.

var aux = window.setTimeout; //save to restore later
window.setTimeout = function(func){
  func();
};

大多数情况下使用假蒂姆会产生相同的结果,但有时可能会失败:

Most times using a fake timout would produce the same result, but some times it may fail:

var obj = {
  functionToTest: function () {
    var foo = 'bar';
    callServer().then(function () {
      alert(foo);
    }, function () {
      //error
    })
    foo = 'buz';
  }
}

正常使用时会提醒 buz 但是假超时会提醒 bar 。请谨慎使用此选项。

When used normal it will alert buz but with the fake timeout it will alert bar. Use this option with caution.

当您使用Q promises时,您指定了成功回调和错误回调,并且它们不需要在测试函数中。

When you use the Q promises you are specifying a success callback and an error callback, and they don't need to be in the tested function.

var obj = {
  functionToTest: function () {
    callServer().then(this.success, this.error)
  },

  success: function () {
    //success
  }
  error: function () {
    //error
  }
}

现在,使用假货超时,你可以测试调用成功和错误函数,然后测试成功和错误函数。

Now, using the fake timeout, you can test that the success and the error functions are called and then test the success and error functions.

如果你需要回调测试函数中的一些数据你可以使用闭包:

If you need some data from the tested function in the callbacks you can use closures:

var obj = {
  functionToTest: function () {
    var data = 'foo';
    callServer().then(this.success(data), this.error)
  },

  success: function (data) {
    var that = this;
    return function () {
      //we have access to data and the object
    }
  }
  error: function () {
    //error
  }
}

进行单元测试时,检查函数的输出对于指定的输入。如果测试函数正在调用一个返回promise的函数,则意味着测试函数的输出是对该函数的调用,因此它应该被测试。稍后您应该测试回调。

When unit-testing you check the output of the function for a specified input. If the tested function is calling a function that returns a promise it means that the output of the tested function was the call to that function, so it is what should be tested. Later you should test the callbacks.

在示例中,我将测试我是否使用预期数据调用callServer,然后测试回调。

In the example I would test that I'm calling callServer with the expected data and then test the callbacks.

如果您需要使用运行和等待(或其他类似选项),则意味着您没有进行单元测试,而是进行功能测试或集成测试。

If you need to use "runs" and "waitsFor" (or other similar options) it means that you are not making unit-testing, you are making functional or integration testing.

单元测试确保项目的每个部分都正常工作,集成测试确保所有部分都能正常工作。

Unit tests ensure that each part of the project is working correctly, and the integration tests ensure that all parts work ok toghether.

如果单元测试过于复杂,则意味着您应该修改正在编程的内容以使其可测试。

If a unit test is too complex, it means that you should modify what you are programing to make it testable.

对于您评论的测试我会做:

For the tests you comment I'd do:

var aux;
beforeEach(function () {
    aux = window.setTimeout;

    window.setTimeout = function(func){
      func();
    };
});

afterEach(function () {
    window.setTimeout = aux;
});


it('should return a single object', function () {
    CrmRestKit.Retrieve(entitySchemaName, fakeid, columns).then(function (data) {
        expect(data.d).not.toBeArray();
    });
});

it('will return the fake-account', function () {
    CrmRestKit.Retrieve(entitySchemaName, fakeid, columns).then(function (data) {
        expect(data.d).toBe(fakeAccount);
    });
});



编辑2:



我是什么提供setTimeout解决方案是一个快速的工作范围,但不是最纯粹的单元测试解决方案,并且很多时候它工作并保持测试简单,但不是这一次。

EDIT 2:

What I was offering with the setTimeout solution was a fast workarround but not the most pure "unit-testing" solution, and many times it works and keeps the tests simple, but not this time.

除了你的代码之外,你正在测试Q和ajax实现,这就是使测试变得复杂的原因。

With your tests you are testing Q and ajax implementation in addition to your code, and that's what's making the tests complicated.

快速解决方案改进了:

让我们从等式中删除promise实现,并考虑它将完成它的工作。

Let's remove the promise implementation from the equation and consider that it will do its job.

您目前希望从承诺中获得您从ajax调用中收到的数据。为什么不测试使用预期数据调用promise的resolve函数?

You are currently expecting to get, from the promise, the data you recieve from the ajax call. Why don't you test that the "resolve" function of the promise is called with the expected data?

单元测试解决方案

不要测试第三方实施,并认为他们会完成自己的工作。

Do not test 3rd party implementations and consider that they will do their job.

我会做3测试:一个用于检查Retrieve是否返回一个promise,另一个用于检查它是否正在使用服务器需要的数据调用ajax,然后在回调函数上调用最后一个来检查它是否使用预期数据调用了resolve(请参阅我的第一个回调测试答案。)

I'd do 3 tests: one to check that Retrieve returns a promise, a second one to check that it is calling the ajax with the data that the server needs and then a last one on the callback function to check that it calls the resolve with the expected data (see my first answer for the callback test).

这篇关于单元测试:Q.js& Jasmine.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆