如果`beforeEach`中的代码是异步的,如何测试Jasmine中的方法?

时间:2012-05-10 04:10:52

标签: javascript unit-testing asynchronous jasmine

我正在尝试使用Jasmine编写一些测试,但如果beforeEach中有一些代码是异步的,现在会出现问题。

示例代码如下:

describe("Jasmine", function() {

    var data ;

    beforeEach(function(){
        console.log('Before each');
        getSomeDataFromRemote(function(res){
            data = res;
        });
    });

    it("test1", function() {
        expect(data).toBe(something);
        console.log('Test finished');
    });

});

您可以在beforeEach中看到,我希望从远程获取一些数据,并将其异步分配给data

但在test1中,当我尝试验证时:

 expect(data).toBe(something);

数据为undefined,因为getSomeDataFromRemote尚未完成。

如何解决?

4 个答案:

答案 0 :(得分:24)

就像it中的异步内容一样,您可以使用beforeEach中的runswaitsFor

define( 'Jasmine' , function () {
    var data ;

    beforeEach(function(){
        runs( function () {
            getSomeDataFromRemote(function(res){
                data = res;
            });
        });

        waitsFor(function () { return !!data; } , 'Timed out', 1000);
    });

    it("test1", function() {
        runs( function () {
              expect(data).toBe(something);
        });
    });
});

虽然我会假设这是因为这是测试代码,但我认为您应该在getSomeDataFromRemote内进行it调用,因为这实际上是您正在测试的内容;)

您可以在我为异步API编写的一些测试中看到一些更大的示例:https://github.com/aaronpowell/db.js/blob/f8a1c331a20e14e286e3f21ff8cea8c2e3e57be6/tests/public/specs/open-db.js

答案 1 :(得分:15)

<强> Jasmine 2.0

要小心,因为在新的Jasmine 2.0中,这将会改变,它将是 mocha 风格。您必须在done()beforeEach()中使用it()功能。例如,假设您想使用jQuery $.get在LAMP服务器中测试页面是否存在且不为空。首先,您需要将jQuery添加到SpecRunner.html文件和spec.js文件中:

describe('The "index.php" should', function() {
    var pageStatus;
    var contents;

    beforeEach(function (done) {
        $.get('views/index.php', function (data, status) {
            contents = data;
            pageStatus = status;
            done();
        }).fail(function (object, status) {
            pageStatus = status;
            done();
        });
    });

    it('exist', function(done) {
        expect(status).toBe('success');
        done();
    });

    it('have content', function(done) {
        expect(contents).not.toBe('');
        expect(contents).not.toBe(undefined);
        done();
    });
});

如您所见,您将函数done()作为beforeEach()it()的参数传递。当您运行测试时,it()将在done()函数中调用beforeEach()后才会启动,因此在您收到服务器的响应之前,您不会启动预期

页面存在

如果页面存在,我们会从服务器的响应中捕获状态和数据,然后调用done()。然后我们检查状态是否“成功”以及数据是否为空或未定义。

该页面不存在

如果页面不存在,我们会从服务器的响应中捕获状态,然后调用done()。然后我们检查状态是否“成功”,数据是否为空或未定义(必须是因为文件不存在)。

答案 2 :(得分:3)

在这种情况下,我通常会将异步调用存根以立即响应。

我不确定您是否看过它,但here是关于使用Jasmine进行异步测试的一些文档。

答案 3 :(得分:0)

我有一篇深入的文章描述了如何使用Jasmine测试异步javascript函数:http://www.larsavery.com/blog/how-to-test-asynchronous-javascript-functions-using-jasmine/