Я знаком с RSpec, где очень легко повторно использовать контрольные примеры, написав общие примеры
shared_example_for 'a cute pet' do
it 'tests that the pet is a small' { expect(pet.size).to be_lesser_than(10) }
it 'tests that the pet can smile' { expect(pet.can_smile?).to be }
end
describe 'The Octocat' do
let(:pet) Octocat.new
it_behaves_like 'a cute pet'
end
...
describe 'The Doge' do
let(:pet) Doge.new
it_behaves_like 'a cute pet'
end
Есть ли эквивалент в Jest? Что-то, что позволило бы мне повторно использовать переменные, установленные в блоках beforeEach ()? Я пытаюсь найти способ, используя что-то вроде следующего:
# __tests__/cuteness.js
export const cutenessTests = function() {
test('it is small', () => {
expect(petSetInBefore.length).toBeLesserThan(5)
})
test('it can smile', () => {
expect(petSetInBefore.canSmile).toBe(true)
})
}
# __tests__/famous_animals.test.js
import { cutenessTests } from './cuteness'
describe('Famous animals', () => {
let petSetInBefore;
describe('Octocat', () => {
beforeEach(() => {
petSetInBefore = new Octocat();
})
cutenessTests.bind(this)()
})
})
Здесь важно то, что я пытаюсь разделить несколько определений test
, а не только одно, иначе я мог бы передать petSetInBefore в общую функцию.
РЕДАКТИРОВАТЬ: каждый из моих тестов и вложенных описаний может изменить мою тестовую среду и объекты, поэтому beforeEach используется для восстановления правильной тестовой среды. Вот лучший пример
class Octocat {
get strokeFor(time) {
this.strokeTime = this.strokeTime + time
if (this.strokeTime <= 10) {
this.mood = 'happy'
} else {
this.mood = 'bored'
}
}
}
class Doge {
get strokeFor(time) {
this.strokeTime = this.strokeTime + time
if (this.strokeTime <= 5) {
this.mood = 'happy'
} else {
this.mood = 'bored'
}
}
}
const cutenessTests = function() {
describe('when stroked for a short while', () => {
beforeEach(() => {
petSetInBefore.strokeFor(1);
})
test('it is happy', () => { expect(petSetInBefore.mood).to(eq('happy')) }
describe('when stroked too much', () => {
beforeEach(() => {
petSetInBefore.stroke(1000);
})
test('it gets bored', () => { expect(petSetInBefore.mood).to(eq('bored')) }
})
describe('when stroked a little longer', () => {
beforeEach(() => {
petSetInBefore.strokeFor(4);
})
test('it is still happy', () => { expect(petSetInBefore.mood).to(eq('happy')) }
})
})
}
РЕДАКТИРОВАТЬ 2: Вот repl.it на основе Ответ Gui3
РЕДАКТИРОВАТЬ3: объект может быть изменен до или во время повторных испытаний
describe('Famous animals', () => {
let petSetInBefore;
describe('Octocat', () => {
beforeEach(() => {
petSetInBefore = new Octocat();
})
describe('when it is not well rested', () => {
beforeEach(() => { petSetInBefore.wellRested() } // Extra object preparation / context before calling reusable examples
cutenessTests()
}),
describe('when it is not well rested', () => {
// Calling reusable examples without extra context
cutenessTests()
})
})
})
3 ответа
Если вы все еще хотите beforeEach ,
По причинам ... это работает, если вы объявите свою переменную в глобальной области видимости
let petSetInBefore; // here it works
describe('Famous animals', () => {
//let petSetInBefore; // here it's undefined
describe('Octocat', () => {
//let petSetInBefore; // undefined too
beforeAll(() => {
petSetInBefore = new Octocat();
})
cutenessTests() // .bind(this) results the same
});
describe('Doge', () => {
beforeEach(() => {
petSetInBefore = new Doge();
})
cutenessTests.bind(this)()
});
})
https://repl.it/@gui3/jestSharedTests
Похоже, что тесты внутри разделяемой функции не могут совместно использовать переменные из beforeEach в противном случае ...
В Jest есть describe.each(table)
, который я не видел используется много раз, но это действительно полезно для повторного использования тестов, которые имеют общие / одинаковые результаты.
В случае одинаковых ожиданий для обоих испытуемых, вы можете сделать это следующим образом:
const aCutePet = pet => {
it("should be small", () => {
expect(pet.size).toBeLessThan(10);
});
it(`should be able to smile`, () => {
expect(pet).toHaveProperty('can_smile', true)
});
}
describe.each([
[new Doge],
[new Octocat]
])("The %O", aCutePet);
Выход:
The Doge { size: 3, can_smile: true }
✓ should be small (1ms)
✓ should be able to smile (1ms)
The Octocat { size: 5, can_smile: true }
✓ should be small
✓ should be able to smile (1ms)
Вы можете просто переместить общие тесты в функцию, которая выполняет вызовы it()
.
class Octocat {
get length() {
return 3;
}
get canSmile() {
return true;
}
}
class GrumpyCat {
get length() {
return 1;
}
get canSmile() {
return false;
}
}
const behavesLikeAPet = (pet) => {
it('is small', () => expect(pet.length).toBeLessThan(5));
it('can smile', () => expect(pet.canSmile).toEqual(true));
};
describe('Famous animals', () => {
describe('Octocat', () => {
behavesLikeAPet(new Octocat());
});
describe('GrumpyCat', () => {
behavesLikeAPet(new GrumpyCat());
});
});
Вы получите подробный вывод для каждого теста:
Famous animals
Octocat
✓ is small (2ms)
✓ can smile (1ms)
GrumpyCat
✓ is small
✕ can smile (2ms)
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.