问题
Suppose I have an index.ts
that will import Database.ts
and run some queries. To test this index.ts
file, I want to mock the Database.ts
because I don't want to connect to any real database.
This is my index.ts
:
import { connect } from './Database'
export async function runSomeQuery() {
const connection = await connect()
const result = await connection.query('SOME QUERY')
return result
}
and here is the mock of database (__mocks__/Database.ts
)
const mockConnection = {
query: jest.fn()
}
export const connect = jest.fn(
() => Promise.resolve(mockConnection)
)
export function __getMockConnection() {
return mockConnection
}
you can see that I expose a __getMockConnection
so that I can get the mockConnection
in my tests (index.spec.ts
) (this pattern is learnt from the official doc):
import { connect, __getMockConnection } from '../Database'
// ^^^^ getting type error here
import { runSomeQuery } from '../index'
jest.mock('../Database')
test('runSomeQuery', async () => {
await runSomeQuery()
const mockConnection = __getMockConnection()
expect(connect).toBeCalled()
expect(mockConnection.query).toBeCalledWith('SOME QUERY')
expect(mockConnection.query).toBeCalledWith('SOME QUERY')
})
The test case does pass as expected, but I'm getting this TypeScript error
Module '"/project/path/Database"' has no exported member '__getMockConnection'. [2305]
TypeScript doesn't know that I'm importing Database
from the mock. Also for this reason I have to disable the diagnostics of ts-jest which complains the same issue.
How can I solve this? Change the import path to '../__mocks__/Database'
doesn't work.
Here is the repo: https://github.com/CodinCat/ts-jest-mock-issue
Open __tests__/index.spec.ts
with an editor that supports TypeScript like VS Code and you will see the error.
回答1:
Since typescript is not aware of jest
mocking, you will need to manually type cast whenever your mocks are different than your actual code:
import * as MockDatabase from "../__mocks__/Database";
import * as Database from "../Database";
import { runSomeQuery } from "../index";
jest.mock("../Database");
// Type cast since Database is automatically mocked by jest
const { connect, __getMockConnection } = Database as typeof MockDatabase;
test("runSomeQuery", async () => {
await runSomeQuery();
const mockConnection = __getMockConnection();
expect(connect).toBeCalled();
expect(mockConnection.query).toBeCalledWith("SOME QUERY");
});
回答2:
Another option is to use ts-jest's mocked() helper. The helper will make sure you have access to the mock test methods. For details have a look at the post here: Import function from a Jest manual mock with Typescript
来源:https://stackoverflow.com/questions/53184529/typescript-doesnt-recognize-my-jest-mock-module