Как провести модульное тестирование модели Mon goose в маршруте Express? - PullRequest
0 голосов
/ 09 мая 2020

У меня возникла проблема при модульном тестировании моего маршрута registerHandler. В этом маршруте используется модель UserModel Mon goose. Моя проблема в том, что я не уверен, как лучше всего насмехаться над ним, так как мне нужно, чтобы он был создан внутри registerHandler.

Я действительно могу издеваться над экземпляром UserModel, используя ts-mockito нормально, но не действительно могу передать его в registerHandler, поскольку мне нужно создать его экземпляр, поскольку мне нужны имя пользователя и пароль от объекта req. Технически я мог бы также переместить создание пользователя на уровень промежуточного программного обеспечения перед этим маршрутом, но тогда я просто перемещаю свою проблему тестирования в другое место.

Я также думал о создании функции createUserModel, которая возвращала бы настоящая UserModel, но которую я мог бы передать в качестве параметра функции registerHandler и имитировать для модульного теста. Хотя тогда у меня возникнут проблемы с тестированием этой новой функции. Но, может быть, поскольку это была бы просто мертвенно-простая функция возврата, было бы нормально не тестировать ее?

Я также изучил jest.mock, однако, чтобы сохранить ввод, мне нужно было вручную издеваться

Всегда используется any, но я оставляю это на крайний случай.

Это что-то лучше решается с помощью интеграционного теста, а не модульного теста? Или я просто ошибаюсь?

databaseModels.ts:

import { Document } from "mongoose"
import { database } from "../database/db"

export interface User {
    username: string
    password: string
}

export const UserModel = database.model<User & Document>(
    "User",
    new database.Schema({
        username: {
            type: String,
            unique: true,
        },
        password: String,
    })
)

registerHandler.ts:

import { Request, Response } from "express"
import { UserModel } from "../databaseModels"

export function registerHandler(
    req: Request,
    res: Response
) {
    const user = new UserModel({
        username: req.body.username,
        password: req.body.password,
    })
    user.save()
        .then(() => {
            res.redirect("/login")
        })
        .catch((err: any) => {
            if (err.code === 11000) {
                res.status(400).send({
                    status: "ERROR",
                    message: "Duplicate user",
                })
            } else {
                res.status(500).send({
                    status: "ERROR",
                    message: "Server error",
                })
            }
        })
}

registerHandler.spe c .ts (используя шутка):

import { Request, Response } from "express"
import { mock, instance, resetCalls } from "ts-mockito"
import { registerHandler } from "./registerRouteHandlers"

describe("registerRouteHandlers", () => {
    const reqMock = mock<Request>()
    const req = instance(reqMock)

    const resMock = mock<Response>()
    const res = instance(resMock)

    beforeEach(() => {
        resetCalls(reqMock)
        resetCalls(resMock)
    })

    describe("registerHandler()", () => {
        it("should create a new user model, save it, then on success redirect to the login page", () => {
            registerHandler(req, res)
            // ...
        })
    })
})
...