Я пишу модульный тест для класса, который использует интерфейс WebAPI браузера.
Я использую ts-mockito для имитации интерфейса (в моем случае это WebGL2RenderingContext).
Когда я запускаю тест, Node выдает ReferenceError: WebGL2RenderingContext is not defined
что понятно, потому что тест выполняется в среде NodeJS, а не в браузере, поэтому класс/интерфейс не существует.
Есть ли способ сделать среду NodeJS осведомленной об интерфейсах WebAPI, чтобы ее можно было издеваться?
ПРИМЕЧАНИЕ. Поскольку это модульный тест, его НЕ следует запускать в реальном браузере.
jsdom кажется возможным решением, но я понятия не имею, как издеваться над ним с помощью ts-mockito.
Следующий фрагмент иллюстрирует то, что я пытаюсь сделать:
import { mock, instance, verify } from 'ts-mockito'
// ========== CLASS ==========
class DummyClass {
dummyMethod() : void {}
}
class TestedClass {
static testDummy(dummy : DummyClass) : void {
dummy.dummyMethod();
}
static testGlCtx(glCtx : WebGL2RenderingContext) : void {
glCtx.flush();
}
}
// ========== TEST ==========
describe('DummyClass', () => {
// This test passed successfully
it('works fine', () => {
const mockDummy = mock(DummyClass);
TestedClass.testDummy( instance(mockDummy) );
verify( mockDummy.dummyMethod() ).once();
});
});
describe('WebGL interface', () => {
it('works fine', () => {
// This line failed with 'ReferenceError: WebGL2RenderingContext is not defined'
const mockGLCtx = mock(WebGL2RenderingContext);
TestedClass.testGlCtx( instance(mockGLCtx) );
verify( mockGLCtx.flush() ).once();
});
});
Запустите с помощью мокко с помощью команды mocha --require ts-node/register 'test.ts'
.
Есть два решения: для обычных DOM API и для универсального имитации.
Как подробно описано в этом ответе StackOverflow, jsdom можно использовать для переноса API-интерфейсов DOM в среду выполнения NodeJS.
Беги npm install --save-dev jsdom global-jsdom
и измените команду Mocha на
mocha --require ts-node/register --require global-jsdom/register 'test.ts'
ПРИМЕЧАНИЕ: global-jsdom — это более новая и обновленная версия jsdom-global.
Это решение работает для распространенных API-интерфейсов DOM (таких как HTMLElement
, SVGElement
, File
),
но это не работает для более специализированных API (WebGL, Crypto, аудио и видео).
Оказывается, у ts-mockito есть способ имитировать интерфейсы, включая DOM и любые веб-API браузера.
Таким образом, приведенный выше тестовый код можно изменить на:
describe('WebGL interface', () => {
it('works fine', () => {
const mockGLCtx = mock<WebGL2RenderingContext>();
TestedClass.testGlCtx( instance(mockGLCtx) );
verify( mockGLCtx.flush() ).once();
});
});
и тест пройдет успешно.