上课:
export class Foo {
private static _count = 0;
id: number;
constructor() {
this.id = ++Foo._count; // starts with 1
}
}
和测试套件:
describe('Foo Class', () => {
describe('constructor', () => {
const fooClassRef = Foo as any; // to pass typechecking
beforeEach(() => {
console.log(`start of beforeEach: ${fooClassRef._count}`);
fooClassRef._count = 0;
console.log(`end of beforeEach: ${fooClassRef._count}`);
});
describe('creating one Foo obj', () => {
console.log(fooClassRef._count);
const foo = new Foo();
it('should have an id of 1', () => {
expect(foo.id).toBe(1);
});
});
describe('creating two Foo objs', () => {
console.log(fooClassRef._count);
const foo1 = new Foo();
const foo2 = new Foo();
it('should have ids of 1 and 2', () => {
expect(foo1.id).toBe(1);
expect(foo2.id).toBe(2);
});
});
});
});
第二项测试失败:
expect(received).toBe(expected) // Object.is equality
Expected: 1
Received: 2
| const foo2 = new Foo();
| it('should have ids of 1 and 2', () => {
> | expect(foo1.id).toBe(1);
| ^
| expect(foo2.id).toBe(2);
| });
| });
结果日志为:
0
1
start of beforeEach(): 3
end of beforeEach(): 0
start of beforeEach(): 0
end of beforeEach(): 0
似乎beforeEach
代码实际上并未运行,直到所有测试都已完成。
答案 0 :(得分:7)
[此答案与Jest和Jasmine都有关系!]
以上示例中的错误是对嵌套describe
,it
和设置/拆卸回调的工作方式的误解。
(请注意,开玩笑it
只是test
的别名)
想象一下,如果您在上面的每个describe / it调用之前添加了beforeEach
,以使嵌套看起来像这样:
┬─ beforeEach 1
└┬ describe Foo Class
├─ beforeEach 2
└┬ describe constructor
├── beforeEach 3
├─┬ describe creating one Foo obj
│ ├─ * - originally constructed a Foo here (but not inside of a beforeEach)
│ ├─ beforeEach 4A
│ └─ it should have an id of 1
└─┬ describe creating two Foo objs
├─ * - originally constructed 2 more Foo's here (but not inside of a beforeEach)
├─ beforeEach 4B
└─ it should have ids of 1 and 2
运行describe
,beforeEach
和it
回调的顺序是:
describe
回调内部的代码最终将首先运行。您可以想到describe
代码的工作是注册it
/ test
回调和beforeEach
回调(以及beforeAll
afterAll
和{ {1}}回调!)。在afterEach
的内部(除了声明var的引用之外),实际上应该没有嵌套在describe
或it
回调中的任何代码-这最终是为什么您的测试最初失败了。
Jest将每个beforeEach
/ it
回调注册为要运行的“测试”,并确保所有test
,beforeAll
,{{ 1}}和beforeEach
回调在嵌套中正确运行。
在给定假设树(其中每个层都有一个afterAll
)的情况下,遵循此方法,结果如下:
解释日志的原始顺序。
为了更好地测试,请使用以下测试代码:
afterEach
请注意:
beforeEach
上-因为重置为每个Foo测试都可以运行,如果Foo有其他方法或测试逻辑。beforeEach(() => {
console.log(1);
const fooClassRef = Foo as any;
fooClassRef._count = 0;
});
describe('Foo Class', () => {
beforeEach(() => console.log(2));
describe('constructor', () => {
beforeEach(() => console.log(3));
describe('creating one Foo obj', () => {
beforeEach(() => console.log('4A'));
test('should have an id of 1', () => {
console.log('A');
const foo = new Foo();
expect(foo.id).toBe(1);
});
});
describe('creating two Foo objs', () => {
let foo1;
let foo2;
beforeEach(() => {
console.log('4B');
foo1 = new Foo();
foo2 = new Foo();
});
it('should have ids of 1 and 2', () => {
console.log(`4B'`);
expect(foo1.id).toBe(1);
expect(foo2.id).toBe(2);
});
it('should originally start with ids of 1 and 2, but they could be changed', () => {
console.log(`4B''`);
expect(foo1.id).toBe(1);
expect(foo2.id).toBe(2);
foo2.id = 47;
expect(foo1.id).toBe(1);
expect(foo2.id).toBe(47);
});
});
});
});
beforeEach
上添加了describe
和beforeEach
,并在其中创建了foo1
和foo2
,因为这是我们为创建“两个Foo objs”测试!现在,我们所有的测试都通过了,该测试套件的结果日志为:
describe
参考