Я использую Karma с Mocha, Chai и Sinon для проверки кода в проекте с использованием этого шаблона. В тесте Subject Test используется API синтеза речи.
Я начинаю с создания window.speechSynthesis.getVoices
в методе beforeEach
beforeEach(() => {
global.window.speechSynthesis = {
getVoices: () => (null),
};
});
Тогда у меня есть два тестовых примера, в каждом из них я хочу проверить, что происходит, когда возвращается другой набор голосов. Для этого я использую заглушки Sinon
Первый тестовый пример
it('supports speech and locale', () => {
const getVoicesStub = sinon.stub(
global.window.speechSynthesis,
'getVoices');
getVoicesStub.callsFake(() => (
[{lang: 'en_US'}]
));
Второй тестовый пример
it('will choose best matching locale', () => {
const getVoicesStub = sinon.stub(
global.window.speechSynthesis,
'getVoices');
getVoicesStub.callsFake(() => (
[{lang: 'es_MX'}, {lang: 'es_US'}]
));
Проблема в том, что когда SUT вызывает window.speechSynthesis.getVoices
во время второго тестового примера, он получает результаты от первого заглушки. Как будто второй заглушка ничего не делает...
Если я прокомментирую первый тестовый пример, второй тестовый пример будет успешным, но если я оставлю их обоих, второй будет терпеть неудачу, потому что возвращается неправильный набор голосов.
Любая идея, как заставить вторую заглушку работать так, как ожидалось?
Ваша заглушка не разрушается между тестами. Вам необходимо восстановить функцию по умолчанию после теста и создать заглушку только один раз before
describe("Test suite", () => {
let getVoicesStub;
before(() => {
// executes before suite starts
global.window.speechSynthesis = {
getVoices: () => (null),
};
getVoicesStub = sinon.stub(global.window.speechSynthesis, 'getVoices');
});
afterEach(() => {
// executes after each test
getVoicesStub.restore();
});
it('supports speech and locale', () => {
getVoicesStub.callsFake(() => ([{lang: 'en_US'}]));
});
it('will choose best matching locale', () => {
getVoicesStub.callsFake(() => ([{lang: 'es_MX'}, {lang: 'es_US'}]));
});
});
afterEach
, но результаты те же. Создание заглушки теперь только в beforeEach
как у вас здесь.
Во-первых, большие до @Troopers. Просто добавив этот ответ, чтобы поделиться окончательным решением и деталями, которые я заметил на этом пути.
Реальный трюк заключался в добавлении переменной уровня тестового уровня, let getVoicesStub
, затем определении метода afterEach
для restore
исходной функции
afterEach(() => {
getVoicesStub.restore();
});
Тонкое замечание к @Troopers предложению об определении окурка в before
тем способом -
Если заглушка определена вне тестовых примеров, я должен использовать beforeEach
, если в тестовых случаях установлен заглушка, я должен использовать метод before
.
В обоих случаях значение afterEach
является критическим! Я поселился в решении beforeEach
поскольку заглушка определена только в одном месте, поэтому немного меньше кода.
describe('Browser Speech', () => {
let getVoicesStub;
beforeEach(() => {
global.window.speechSynthesis = {
getVoices: () => (null),
};
getVoicesStub = sinon.stub(
global.window.speechSynthesis,
'getVoices');
});
afterEach(() => {
getVoicesStub.restore();
});
it('supports speech and locale', () => {
getVoicesStub.callsFake(() => (
[{lang: 'en_US'}]
));
// test case code ..
});
it('will choose best matching locale', () => {
getVoicesStub.callsFake(() => (
[{lang: 'es_MX'}, {lang: 'es_US'}]
));
// test case code ..
});
});
before
темbeforeEach
если перенесу заглушку вbeforeEach
?