首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在这个测试中_this.debug不是一个函数?

为什么在这个测试中_this.debug不是一个函数?
EN

Stack Overflow用户
提问于 2020-12-04 23:09:39
回答 1查看 359关注 0票数 0

我正在开发一个项目的概念证明。我使用的是Node.js和express.js,我正在尝试使用jest.js对其进行单元测试。这是一个返回简单硬编码消息的简单API。

我的目的是测试一下,当调用路由时,debug会记录消息"Health check“。

我在下面的单元测试中遇到了问题(我知道我的测试中没有断言,这将是测试通过后的下一步):

app/tests/server/routes/health-check/HealthCheck.test.js失败(24.196秒)

特性#1:记录运行状况检查请求> whenRouting_thenDebugShouldSendTheRouteMessage

代码语言:javascript
复制
TypeError: _this.debug is not a function

   7 |         this.router = router;
   8 |         this.route = (request, response) => {
>  9 |             this.debug('Health check');
     |                  ^
  10 |             response.send({"Health check": "Passed!"});
  11 |         }
  12 |     }

  at HealthCheck.route (app/server/routes/health-check/HealthCheck.js:9:18)
  at Object.<anonymous> (app/tests/server/routes/health-check/HealthCheck.test.js:35:21)

我怀疑debug没有绑定到测试实例。我该如何着手解决这个问题呢?

此外,当我运行代码时,一切工作正常。

下面是我的测试类:

代码语言:javascript
复制
import HealthCheck, {ROUTE_NAME} from "../../../../server/routes/health-check/HealthCheck";
import debug from 'debug';
import express from "express";

jest.mock('debug');

const extendMock = jest.fn();
const requestMock = jest.fn();
const responseMock = jest.fn(() => {
    return {
        send: jest.fn()
    };
});


debug.extend = extendMock;

let healthCheck;

describe('Feature #1: Logging health check request', () => {
    beforeEach(() => {
        setup();
    });

    test('whenBuildingRoute_thenDebugShouldExtendWithTheRouteName', () => {
        expect(debug.extend.mock.calls[0][0]).toBe(ROUTE_NAME);
    });

    test('whenCreatingRoute_thenTheRouterShouldBeReturned', () => {
        let router = healthCheck.create();
        expect(router).toBe(express);
    });

    test('whenRouting_thenDebugShouldSendTheRouteMessage', () => {
        healthCheck.route(requestMock, responseMock);
    });

});

function setup() {
    express.mockClear();
    debug.mockClear();
    extendMock.mockClear();
    requestMock.mockClear();
    responseMock.mockClear();

    healthCheck = new HealthCheck(express, debug);
}

下面是我要测试的类:

代码语言:javascript
复制
export const ROUTE_PATH = "/health-check";
export const ROUTE_NAME = "health-check";

export default class HealthCheck {
    constructor(router, debug) {
        this.debug = debug.extend(ROUTE_NAME);
        this.router = router;
        this.route = (request, response) => {
            this.debug('Health check');
            response.send({"Health check": "Passed!"});
        }
    }

    create() {
        this.router.get(ROUTE_PATH, this.route);
        return this.router;
    }
}

这里还有一个我已经有的测试类,所有的测试都通过了,我不知道有什么不同。

代码语言:javascript
复制
import LoggingMiddleware, {
    BUILDING_MIDDLEWARE_MESSAGE, HTTP_REQUEST_MESSAGE,
    MIDDLEWARE_NAME
} from "../../../server/middlewares/LoggingMiddleware";
import express from 'express';
import debug from 'debug';
import {expressMockListen, expressMockUse} from "../../../../__mocks__/express";

jest.mock('debug');

const REQUEST_METHOD = "A method";

const requestMock = jest.fn(()=>{
    return {
        method: REQUEST_METHOD,
        path: jest.fn(),
        headers: jest.fn(),
        query: jest.fn(),
        body: jest.fn()
    }
});
const responseMock = jest.fn();
const nextMock = jest.fn();

let loggingMiddleware;

describe('Feature #1: Logging HTTP requests', () => {
    beforeEach(() => {
        setup();
    });

    test('whenBuildingAMiddleware_thenTheLoggerShouldDebugAMessage', () => {
        expect(debug.mock.calls[0][0]).toBe(BUILDING_MIDDLEWARE_MESSAGE);
    });

    test('whenGettingName_thenTheNameShouldBeReturned', () => {
        expect(loggingMiddleware.getName()).toBe(MIDDLEWARE_NAME);
    });

    test('whenGettingTheMiddlewareFunction_thenExpressUseShouldBeCalled', () => {
        loggingMiddleware.getMiddlewareFunction();
        expect(expressMockUse).toHaveBeenCalled();
    });

    test('whenGettingTheMiddlewareFunction_thenExpressRouterShouldBeReturned', () => {
        const router = loggingMiddleware.getMiddlewareFunction();
        expect(router).toBe(express);
    });

    test('whenLogging_thenNextShouldBeCalled', () => {
        loggingMiddleware.log(requestMock, responseMock, nextMock);
        expect(nextMock).toHaveBeenCalled();
    });

    test('whenLogging_thenTheMessageShouldBeLogged', () => {
        loggingMiddleware.log(requestMock, responseMock, nextMock);
        expect(debug.mock.calls[1][0]).toBe(HTTP_REQUEST_MESSAGE);
    });
});

function setup() {
    express.mockClear();
    expressMockUse.mockClear();
    expressMockListen.mockClear();
    debug.mockClear();

    requestMock.mockClear();
    responseMock.mockClear();
    nextMock.mockClear();

    loggingMiddleware = new LoggingMiddleware(express, debug);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-05 01:00:22

extendMock是一个存根,所以预计模拟的debug.extend会返回undefined而不是函数。

如果模块需要更具体的mock,则需要将auto-mock替换为手动mock。可以通过导出公开debug.extend以便在测试中直接访问的函数:

代码语言:javascript
复制
import debug, { mockDebugInstance } from 'debug';

jest.mock('debug', () => {
  const mockDebugInstance = jest.fn();
  const mockDebug = jest.fn().mockReturnValue({
    extend: jest.fn().mockReturnValue(mockDebugInstance);
  };

  return {
    __esModule: true,
    default: mockDebug,
    mockDebugInstance
  };
});

...

expect(debug.extend).toBeCalledWith(...);
expect(mockDebugInstance).toBeCalledWith(...);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65145986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档