2012-05-10 41 views
20

我试图用Jasmine写一些测试,但现在有一个问题,如果有一些代码是异步的在beforeEach如何测试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尚未完成。

如何解决?

+0

我知道摩卡可以做异步设置,但我不太熟悉茉莉花。你有没有尝试在你的'beforeEach'中使用[异步规范结构](https://github.com/pivotal/jasmine/wiki/Asynchronous-specs)?文档只显示它们在规范中使用,但它们也可能在'beforeEach'中运行。 –

回答

23

就像一个it内异步的东西,你可以使用runswaitsFor在beforeEach:

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

+2

等待已经停止在Jasmine中运行。现在,您可以使用done()。希望这有助于 - http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support –

3

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

我不确定你是否看过它,但​​是关于与Jasmine进行异步测试的一些文档。

+0

我刚刚检查了你的链接,但仍然不知道如何在我的情况下做到这一点。 – Freewind

+0

您可以将'getSomeDataFromRemote'调用包装在'runs'函数中,以及期望。您可以使用'waits'来提供一段足够长的时间,然后再运行您的期望。确实很费劲,并且可能导致随机失败。这就是为什么我只是存根电话立即返回。 [Sinon.js](http://sinonjs.org/)在ajax存根区域也提供了一些帮助,如果你更喜欢金属之外的东西。 – x1a4

+0

谢谢,'runs'和'waitsFor'正是我正在寻找的。但是,@Slace给了我一个工作和细节的例子,我不得不接受他的回答。对不起〜 – Freewind

15

Jasmine 2.0

要小心,因为在新的茉莉花2.0,这是不会改变,这将是摩卡风格。您必须使用done()函数beforeEach()it()。例如,假设您想在LAMP服务器中使用jQuery $.get来测试页面是否存在并且不是空的。首先,你需要的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()将不会启动,直到在beforeEach()函数中调用done()为止,所以在获得服务器的响应之前,您不会启动期望。

的页面存在

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

的页面不存在

如果该页面不存在,我们捕获来自服务器的响应的状态,我们称之为done()。然后我们检查状态是不是“成功”,以及数据是空的还是未定义的(这一定是因为文件不存在)。

+0

'done()'也适用于[minijasminenode](https://github.com/juliemr/minijasminenode) –

+0

等项目,我发现beforeAll不支持异步样式。下面的规范将在beforeAll调用之前运行“完成“ – Kaicui

+2

为什么将'''''''传递给''''''''''函数并调用?如果它们从'''it'''中被省略了会出什么问题? – paulhhowells

相关问题