gpt4 book ai didi

TypeScript+Jest - 如何将 jest.spyOn 与通用 TypeScript 方法一起使用?

转载 作者:行者123 更新时间:2023-12-05 06:14:36 27 4
gpt4 key购买 nike

我定义了以下 TypeScript 对象:

// HttpClient.ts
export type HttpResponse<T> = Response & {
data?: T;
}

async function get<T>(url: string, args: RequestInit = {}): Promise<HttpResponse<T>> {
return fetchRequest<T>(url, {...args, method: 'get'}) // fetchRequest returns value of type Promise<HttpResponse<T>>
}

export default {get} // default export represents an HttpClient object

我还有另一个文件 getFeatureFlag.ts,它在其实现中使用了这个 HttpClient:

// getFeatureFlag.ts
import HttpClient from '../httpClient'

export type FetchResponse<T = any, E = any> = {
data: Nullable<T>;
error: Nullable<E>;
}

export type FeatureFlag = {
toggleActive: boolean; // true/false denotes show/hide feature
}

export async function getFeatureFlag(flagName: string): Promise<FetchResponse<boolean, string>> {
const response = await HttpClient.get<FeatureFlag>(`/v1/toggles/${flagName}/`)

// ... rest of the implementation ...
}

我正在为 getFeatureFlag.test.ts 下的这个文件编写单元测试(使用 Jest),其中包含以下代码片段:

// getFeatureFlag.test.ts
import HttpClient, {HttpResponse} from '../httpClient'
import {getFeatureFlag, FLAG_STORE, FeatureFlag} from '../index'

describe('getFeatureFlag', () => {
beforeEach(async () => {
// vv === THIS LINE IS WHAT THIS POST IS ABOUT === vv
jest.spyOn<HttpResponse<FeatureFlag>, 'get'>(HttpClient, 'get').mockImplementationOnce(() => ({
ok: true,
data: {
toggleActive: true,
},
}))

result = await getFeatureFlag(flagName)
})

it('then perform api request for feature flag data', () => {
expect(HttpClient.get).toHaveBeenCalledWith('/v1/toggles/featureFlag/')
})
})

@types/jest 定义文件中,spyOn 函数定义如下:

function spyOn<T extends {}, M extends FunctionPropertyNames<Required<T>>>(
object: T,
method: M
): Required<T>[M] extends (...args: any[]) => any
? SpyInstance<ReturnType<Required<T>[M]>, ArgsType<Required<T>[M]>>
: never;

我很难让 TypeScript 编译器正确读取下面的代码片段而没有问题。

jest.spyOn<HttpResponse<FeatureFlag>, 'get'>(HttpClient, 'get').mockImplementationOnce(() => ({
ok: true,
data: {
toggleActive: true,
},
}))

通过上述设置,编译器告诉我 get 不满足约束 never 并且我不知道如何解决此处的输入问题以获取我的测试编写/运行正确。我在这里尝试做的另一件事是只返回 HttpResponsePartial 因为我显然不想在单元测试中填写每个字段不需要它们。

有没有人能够通过泛型正确应用 jest.spyOn 来帮助解决这个问题?

最佳答案

认为你所缺少的只是这个词 async在您调用 mockImplementationOnce() 的电话中.然后您可以删除 jest.spyOn 的类型参数.你不会在你的模拟实现中自动获得类型安全,但如果你真的担心它,你可以添加 as HttpResponse<FeatureFlag> .

let result: FetchResponse<boolean, string>;

describe('getFeatureFlag', () => {
beforeEach(async () => {
// missing
// ↓
jest.spyOn(HttpClient, 'get').mockImplementationOnce(async () => ({
ok: true,
data: {
toggleActive: true,
},
} as HttpResponse<FeatureFlag>));

result = await getFeatureFlag(flagName);
})
});

TS Playground

当然,这并没有回答标题中提出的问题,但它应该可以修复您的代码。我花了很长时间试图让你指定的泛型类型参数起作用,但最终放弃了。它可能是对 jest 中声明的限制命名空间。

关于TypeScript+Jest - 如何将 jest.spyOn 与通用 TypeScript 方法一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62826474/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com