gpt4 book ai didi

javascript - 如何模拟正在测试的服务调用的函数的实现?

转载 作者:行者123 更新时间:2023-12-02 22:42:14 25 4
gpt4 key购买 nike

我正在开发一个 NestJS 项目,我需要为我的服务编写单元测试。

我有一个名为 BigQueryService 的服务,它使用 @google-cloud/bigquery 访问 Big Query 数据集并执行查询。我还有另一个服务(我们称之为 MyService),其工作是根据其他逻辑构建我需要的查询,并将其传递给 BigQueryService,从中接收查询结果并将其返回给 Controller , Controller 将在然后通过端点发送数据。

我需要为 MyService 编写单元测试,为此我需要以不需要解析 BigQueryService 依赖项的方式模拟 BigQueryService。这是我的一些代码:

bigquery.service.ts:

import { Injectable } from '@nestjs/common';
import { BigQuery } from '@google-cloud/bigquery';
...
@Injectable()
export class BigqueryService {
...
constructor(
...
) {
...
}

async executeQuery(querySentence: string): Promise<Array<any>> {
...
return response;
}
}

MyService.service.ts:

import { Injectable } from '@nestjs/common';
import { BigqueryService } from '../bigquery/bigquery.service';
//the following is just a service that helps log the results of this service
import { MyLogger } from '../../config-service/logger.service';
...
@Injectable()
export class MyService {
constructor(
private readonly bigqueryService: BigqueryService,
private readonly logger: MyLogger,
) { }
...
async myFunc(request: RequestInterface): Promise<Array<ResponseInterface>> {
let query = (some code to create a query i want)
return await this.bigqueryService.executeQuery(query);
}

对于测试,我遵循了此线程中的答案:Mock a method of a service called by the tested one when using Jest

jest.mock('../services/bigquery/bigquery.service', () => jest.fn()) 
const bq = require('../services/bigquery/bigquery.service')
jest.mock('../config-service/logger.service', () => jest.fn())
const ml = require('../config-service/logger.service')

const executeQuery = jest.fn()
executeQuery.mockReturnValue('desired value')
bq.mockImplementation(() => ({executeQuery}))


describe("Testing consumption moment service function", () => {

it("should call the mock service", () => {
const ms = new MyService(bq,ml)
ms.myFunc(requestBody) //requestBody is a RequestInterface
expect(bq.executeQuery).toHaveBeenCalled
expect(bq.executeQuery).toHaveReturned
});
});

该测试通过了,所以我假设我正确地模拟了 bigquery 服务。但是,当我尝试断言返回的值是正确的值时,我将测试设为异步,以便在 myFunc 实际运行完成并且我可以比较结果之前测试不会完成。

 it("should call the mock service", async () => {
const ms = new MyService(bq,ml)
await ms.myFunc(requestBody)
expect(bq.executeQuery).toHaveBeenCalled
expect(bq.executeQuery).toHaveReturned
});

这会出现错误:TypeError:this.bigqueryService.executeQuery 不是函数该错误指向 myFunc 调用 this.bigqueryService.executeQuery 的行。

我尝试了不同的模拟示例,以便可以模拟对此函数的调用,但没有一个像上面的示例那么接近。我也尝试过使用

jest.spyOn(bq, 'executeQuery') 

但这也说明了executeQuery 不是一个函数:无法监视executeQuery 属性,因为它不是一个函数;改为未定义

有人能给我指出正确的方向吗?我是否缺少某些东西来使此测试正常进行?我预先感谢你们能给我的任何帮助。

最佳答案

我最终弄清楚了,所以如果有人遇到同样的情况,我在这里找到了答案:https://jestjs.io/docs/en/jest-object

测试是这样修复的:

jest.mock('../config-service/logger.service', () => jest.fn())
const ml = require('../config-service/logger.service')
const executeQuery = jest.fn()

describe("Testing service function", () => {

it("should call the mock service", async () => {
jest.mock('../services/bigquery/bigquery.service', () => {
return {
executeQuery: jest.fn(() => 'desired output'),
};
})
const bq = require('../services/bigquery/bigquery.service')

const ms = new MyService(bq,ml)
const p = await ms.myFunc(requestBody) //requestBody is a RequestInterface
expect(bq.executeQuery).toHaveBeenCalled
expect(bq.executeQuery).toHaveReturned
expect(p).toEqual(desired result)
});
});

关于javascript - 如何模拟正在测试的服务调用的函数的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58547135/

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