#typescript #jestjs #pouchdb
#typescript #jestjs #pouchdb
Вопрос:
Я хотел бы написать модульный тест, который использует смоделированные ответы PouchDB, но я изо всех сил пытаюсь заставить Jest, Typescript и PouchDB хорошо работать вместе. По общему признанию, потому что я не совсем понимаю все тонкости Typescript.
Я хочу смоделировать следующий модуль. Ничего особенного, он считывает некоторую глобальную конфигурацию и возвращает новый экземпляр PouchDB.
import PouchDB from "pouchdb";
export class CouchDbProvider {
getCouchDb(dbName:string): PouchDB.Database<{}> {
const config = (window as any).config || (global as any).config; // ('global' is for unit tests)
const {COUCHDB_URL: couchDbUrl} = config;
return new PouchDB(
`${couchDbUrl}${dbName}`,
{
skip_setup: true
});
}
}
export default new CouchDbProvider();
При вызове вышеупомянутой функции getCouchDb() она должна вернуть макет экземпляра PouchDB, который я могу настроить.
И вот тут я испытываю трудности. Часть моего кода модульного тестирования, в которой я пытаюсь выполнить макет, выглядит следующим образом…
import PouchDB from "pouchdb";
import couchDbProvider from "../../providers/couch-db-provider";
jest.mock('../../providers/couch-db-provider')
jest.mock('pouchdb');
const mockedCouchDbProvider = couchDbProvider as jest.Mocked<typeof couchDbProvider>;
const mockedPouchDb = PouchDB as jest.Mocked<typeof PouchDB>;
mockedCouchDbProvider.getCouchDb.mockReturnValue(mockedPouchDb);
Компиляция Typescript завершается ошибкой в последней строке с: TS2345: Argument of type 'Mocked<Static>' is not assignable to parameter of type 'Database<{}>'. Type '{ plugin: MockInstance<Static, ["This should be passed to PouchDB.plugin()"]>; version: string; fetch: MockInstance<Promise<Response>, [string | Request, RequestInit?]>; ... 16 more ...; eventNames: MockInstance<...>; } amp; Static' is missing the following properties from type 'Database<{}>': find, createIndex, getIndexes, deleteIndex, and 29 more.
Что я здесь делаю не так?
Ответ №1:
После некоторых экспериментов и создания прототипов мне удалось это выяснить. Приведенные ниже имена переменных можно упростить, но я поделюсь кодом как есть для наглядности.
Вот как заставить Jest, PouchDB и Typescript хорошо работать вместе:
import PouchDB from "pouchdb";
import couchDbProvider from "../../providers/my-custom-couch-db-provider";
jest.mock('../../providers/my-custom-couch-db-provider');
jest.mock('pouchdb');
const mockedCouchDbProvider = couchDbProvider as jest.Mocked<typeof couchDbProvider>;
// This is actually creates a **mocked pouchDb instance**. When we told Jest to import the pouchDb module it replaced constructors with ones that creates mocks.
const mockedPouchDbInstance = new PouchDB();
// We do this just so we can configure the mock pouchDb's methods in a type safe way.
const mockedPouchDbConfig = mockedPouchDbInstance as jest.Mocked<typeof mockedPouchDbInstance>;
mockedCouchDbProvider.getCouchDb.mockReturnValue(mockedPouchDbInstance);
mockedPouchDbConfig.get.mockResolvedValue(/* etc etc */);