[Этот ответ актуален как для Джеста, так и для Жасмин!]
Ошибка в приведенном выше примере - неправильное понимание того, как работают обратные вызовы вложенности describe
, it
и установки / разрыва.
(Обратите внимание, что для jest it
это просто псевдоним для test
)
Представьте, что вы добавили 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
и afterEach
обратных вызовов!). На самом деле не должно быть никакого кода внутри ваших describe
(кроме объявления var для ссылки), который не был бы вложен в обратный вызов it
или beforeEach
- поэтому в конечном итоге ваш тест изначально провалился ,
Jest будет регистрировать каждый обратный вызов it
/ test
как «Тест» для запуска и будет гарантировать, что все обратные вызовы beforeAll
, beforeEach
, afterAll
и afterEach
бегите соответственно к их вложенности.
Следуя этой методологии с учетом гипотетического дерева (где каждый слой имеет beforeEach
), это приводит к следующему порядку:
- изначально построил Foo здесь (но не внутри beforeEach)
- изначально построил еще 2 Foo здесь (но не внутри beforeEach)
- beforeEach 1
- beforeEach 2
- beforeEach 3
- beforeEach 4A
- должен иметь идентификатор 1
- beforeEach 1
- beforeEach 2
- beforeEach 3
- beforeEach 4B
- он должен иметь идентификаторы 1 и 2
Что объясняет первоначальный порядок бревен.
Чтобы лучше проверить это, давайте вместо этого воспользуемся следующим тестовым кодом:
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
на верхнем уровне набора тестов - поскольку сброс этого значения для каждого теста Foo, который вы могли бы запустить, был бы хорошей идеей, если бы у Foo были другие методы или логика для тест.
- Мы добавили еще один тест к «созданию двух объектов Foo»
describe
- Мы добавили
beforeEach
, где мы создаем наши foo1
и foo2
к этому describe
, так как это настройка, которую мы хотим выполнить для обоих наших тестов "создания двух Foo objs"!
Теперь все наши тесты пройдены, и полученный журнал этого набора тестов выглядит так:
1
2
3
4A
1
2
3
4B
4B'
1
2
3
4B
4B''
Ссылки