您似乎可以将“内容”放在describe
内,但在it
之外:
describe('1', function() {
var foo = 'bar';
console.log(foo);
it('1a', function(done) {
expect(true).toBe(true);
done()
});
it('1b', function(done) {
expect(true).toBe(true);
done();
});
});
似乎你可以将it
块放在一个名为的函数中:
describe('1', function() {
(function() {
it('1a', function(done) {
expect(true).toBe(true);
done()
});
it('1b', function(done) {
expect(true).toBe(true);
done();
});
})()
});
在这两种情况下,输出都是:
~/code/study-buddies $ jasmine-node server
bar
..
Finished in 0.005 seconds
2 tests, 2 assertions, 0 failures, 0 skipped
但是当我尝试将it
块放在Node request回调中时,它似乎没有运行测试:
describe('1', function cb1() {
var foo = 'bar';
console.log(foo);
var request = require('request');
request.get('http://localhost:3000/api/posts', function() {
console.log('here');
it('1a', function cb1a(done) {
console.log('1a');
expect(true).toBe(true);
done();
});
it('1b', function cb1b(done) {
console.log('1b');
expect(true).toBe(true);
done();
});
});
});
输出:
~/code/study-buddies $ jasmine-node server
bar
Finished in 0.007 seconds
0 tests, 0 assertions, 0 failures, 0 skipped
here
当我运行我的真实代码时:
var request = require('request');
var base_url = 'http://localhost:3000/api/posts';
describe('Posts', function() {
var post;
beforeEach(function(done) {
var options = {
url: base_url,
method: 'POST',
json: {
title: 'one'
}
};
request(options, function(err, response, body) {
if (err) console.log('ERROR IN THE SET UP.');
else { post = body; }
done();
});
});
afterEach(function(done) {
request.del(base_url+'/'+post._id, function(err, response, body) {
if (err) console.log('ERROR IN THE TEAR DOWN.');
else { post = null; }
});
done();
});
describe('GET /', function() {
it('returns a status code of 200', function(done) {
request.get(base_url, function(err, response, body) {
expect(response.statusCode).toBe(200);
done();
});
});
it('returns the right posts', function(done) {
request.get(base_url, function(err, response, body) {
expect(JSON.parse(body)).toEqual([post]);
done();
});
});
});
describe('GET /:id', function() {
it('returns a status code of 200', function(done) {
request.get(base_url+'/'+post._id, function(err, response, body) {
expect(response.statusCode).toBe(200);
done();
});
});
it('returns the right post', function(done) {
request.get(base_url+'/'+post._id, function(err, response, body) {
expect(JSON.parse(body)).toEqual(post);
done();
});
});
});
describe('POST /', function() {
var options = {
url: base_url,
method: 'POST',
json: {
title: 'two'
}
};
request(options, function(err, response, body) {
it('returns a status code of 201', function(done) {
expect(response.statusCode).toBe(201);
done();
});
it('returns the created Post', function(done) {
expect(body).toEqual({title: 'two'});
done();
});
});
});
describe('PUT /:id', function() {
});
describe('DELETE /:id', function() {
});
});
我没有输出:
~/code/study-buddies $ jasmine-node server
~/code/study-buddies $
为什么会这样?
注意:我正在尝试将it
块嵌套在request
下,因为两个it
块正在发出相同的请求,所以我想要干。
答案 0 :(得分:4)
这里有两个步骤:
it()
)。在第一个示例中,定义了测试,同时处理步骤1.在第二个示例中(使用回调),您在{2}期间执行调用it
,因此Jasmine不会处理它们。
如何处理
您需要定义单独的测试,或者只使用回调内的expect()
来电,而无需拨打it()
。
如果您需要将请求发送到同一路由,但使用不同的参数,通常需要定义单独的测试。典型示例是使用有效和无效数据测试API行为:
describe('POST /users/', function() {
it('should create user', function (done) {
request.post('/users/', { /* valid data */ }, function () { /* expect clauses */ });
});
it('should respond with errors given invalid data', function (done) {
request.post('/users/', { /* invalid data */ }, function () { /* expect clauses */ });
});
});
当您想要测试单个请求的不同部分时,您希望在单个测试中使用多个expect()
语句。例如,检查响应代码和几个参数的值:
describe('GET /users/{id}/', function() {
it('should return user', function (done) {
request.get('/users/14/', function (err, response, body) {
expect(response.code).toBe(200);
expect(body.username).toBe('test');
expect(body.email).toBe('test@example.com');
});
});
});
显然存在一些中间案例,由您来决定每个具体案例是否足够重要,可以进行单独的测试(并复制相同的请求),或者可以通过其他expect()
语句来处理在单一测试中。
深入解释
这需要读者的一些背景知识:
forEach
)继续之前的一些事实:
describe()
的调用之后,它开始执行收集的测试。describe()
和it()
的调用是同步的,而HTTP请求的执行是异步的(使用事件循环)。describe()
为测试创建命名空间,并同步调用作为第二个参数提供的函数。 it()
将它的第二个参数添加为当前命名空间的测试。让我们追踪你的第一个案例:
describe()
创建名称空间1
并同步执行cb1()
。it()
同步添加测试1a
。it()
同步添加测试1b
。cb1()
的执行,以及测试收集步骤。添加IIFE不会改变任何内容,因为它只是同步调用它。
让我们追踪你的第二个案例:
describe()
创建名称空间1
并同步执行cb1()
。cb1()
的执行,以及测试收集步骤。it()
尝试添加测试1a
,但测试执行已经完成。此时应该清楚的是,您不能也不应该在异步回调中定义测试。所以你的第三个例子永远不应该写。并且不应该问为什么它在没有任何输出的情况下完成。
但是出于兴趣,我查看了Jasmine源代码并进行了一些调试以查看实际发生的情况。你走了。
您可能已经注意到函数describe()
和it()
不是由您导入的,而是由Jasmine本身提供的。除了为您导入这些函数外,Jasmine还提供了it()
和describe()
用于收集测试的一些内部状态。导入测试时,此内部状态已设置,但运行时则不然。
当您从请求回调中调用it()
时,您在运行测试阶段执行此操作,并且未设置内部设置。所以它失败并出现Error: jasmine.Suite() required
错误。此错误导致Jasmine立即退出而没有任何输出。
您可能会问为什么在第二个示例中打印结果呢?这很简单:在你的第二个例子中,你没有任何其他测试,所以在调用it()
时,结果已经打印出来了。您可以通过在console.log()
的来电之间添加另一个it()
来进行检查(它永远不会被打印)。