如何使用 jest 在 nodejs 中模拟 redis 客户端

时间:2021-01-11 11:41:54

标签: node.js unit-testing redis mocking

我尝试使用 private boolean fail = false; @Override public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException { Log log = helper.getLog(); List<String> lines = Collections.emptyList(); try { Path path = Paths.get((String) helper.evaluate("${versions.outputFile}")); lines = Files.readAllLines(path); fail = lines.stream() .anyMatch(l -> l.contains("The parent project has a newer version")); } catch (Exception ex) { log.warn(ex); fail = false; } if (this.fail) { throw new EnforcerRuleException(lines.toString()); } } @Override public boolean isCacheable() { return false; } @Override public boolean isResultValid(EnforcerRule enforcerRule) { return fail; } @Override public String getCacheId() { return null; } @Override public EnforcerLevel getLevel() { return EnforcerLevel.WARN; } } redis-mock 来模拟 redisClient.js。但我找不到解决方案。请给我一个代码示例。我需要在 jest 中模拟它。

redisClient.js

controller

控制器

const redis = require('redis');
const asyncRedis = require("async-redis");

//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
    {
        retry_strategy: function(options) {
          if (options.error && options.error.code === "ECONNREFUSED") {
            // End reconnecting on a specific error and flush all commands with
            // a individual error
            return new Error("The server refused the connection");
          }
          if (options.total_retry_time > 1000 * 60 * 60) {
            // End reconnecting after a specific timeout and flush all commands
            // with a individual error
            return new Error("Retry time exhausted");
          }
          if (options.attempt > 10) {
            // End reconnecting with built in error
            return undefined;
          }
          // reconnect after
          return Math.min(options.attempt * 100, 3000);
        },
    }
);

module.exports = asyncRedis.decorate(connection);

服务

const logger = require('../../helper/logger');
const response = require("../../config/response");
const constant = require('../../config/constant');
const QuizService = require('../../services/quiz/quizService');

class QuizController {

    constructor() {
        this.quizService = new QuizService();
    }

    async getQuiz(req, res) {
        const { userId, query: { campaignId } } = req;
        try {
            const question = await this.quizService.getQuestion(userId, campaignId);

            res.send(response.res(true, constant.MSG.Quiz_FETCHED, question));

        } catch (error) {

            res.status(constant.RESPONSE.INTERNAL_ERROR.CODE)
                .send(response.res(false, error.message, null, error.code))
        }
    }
}

我的单元测试代码

const _ = require('lodash');
const moment = require('moment');
const { Op } = require('sequelize');
const { v4: uuidv4 } = require("uuid");
const shuffle = require('shuffle-array');
const serialize = require("serialize-javascript");
const utill = require("../../helper/util");
const redis = require("../../cache/redisClient");
const constant = require('../../config/constant');
const scoreHelper = require('./../../helper/scoreHelper');
const db = require("../../models");
const Quiz = db.quiz;
const Campaign = db.campaign;
const campaign = require('../campaign/campaignService')
const SubscriberAnswer = require('../subscriberAnswer/subscriberAnswerService')
const SubscriberProgram = require('../subscriberProgram/SubsciberProgramService')

class quizService {

    constructor() {
        this.subscriberAnswer = new SubscriberAnswer()
        this.subscriberProgram = new SubscriberProgram()
        this.campaign = new campaign()
    }

    async getQuestion(userId, campaignId) {
        const subscribedProgramData = await this._checkAvailableQuestionLimit(userId, campaignId)
        if(!subscribedProgramData){
            throw { message: constant.MSG.TRY_AGAIN }
        }
        if (subscribedProgramData.no_of_questions > 0) {
            const question = await Quiz.findQuestion(userId, campaignId);
            if (question.length) {
                const data = {
                    subscriber_id: userId,
                    campaign_id: campaignId,
                    questions_id: question[0].id
                }
                const updateData = {
                    id: subscribedProgramData.id,
                    no_of_questions: (subscribedProgramData.no_of_questions - 1)
                }
                await this.subscriberAnswer.create(data);
                await this.subscriberProgram.updateQuota(updateData);
                const id = uuidv4();
                const {answer, ...questionData } = question[0];
                const responseData = await this.handleQuestionData(id, userId, campaignId, questionData, answer);
                return responseData;
            } else {
                throw { code:constant.RESPONSE_COEDES.ALL_ANSWERED, message: constant.MSG.ANSWER_ALL }
            }
        } else {
            throw { message: constant.MSG.QUOTA_OVER }
        }
    }
}

错误

const QuizService = require("../../src/services/quiz/quizService");
const QuizController = require("../../src/controllers/quiz/quizController");
const quizService = new QuizService();
const quizController = new QuizController();
const httpMocks = require("node-mocks-http");

jest.mock("../../src/helper/logger");
jest.mock("../../src/cache/redisClient.js");

beforeEach(() => {
    req = httpMocks.createRequest();
    res = httpMocks.createResponse();
    next = jest.fn();
    jest.resetAllMocks();
    quizService.getQuestion = jest.fn();
});
quizService.getQuestion = jest.fn();
const response = {
    id: 1,
    name: 'Sandun',
    msisdn: '94704377575',
    otp: '1234',
    deleted: 0,
    attempts: 0,
    img_url: 'https://'
}

// This test shows how the constructor can be mocked, and how to spy on passed parameters.
describe("Test QuizController", () => {
    afterEach(() => {
      jest.resetAllMocks();
    });

    //Because getQuestion is prototype method
    it("Test - GetQuiz - Success", async () => {
        req.query.programId = 1;
        req.userId = 1;
        jest.spyOn(QuizService.prototype, "getQuestion").mockReturnValue(response);
        await quizController.getQuiz(req, res);
        expect(res.statusCode).toBe(200);
    });

});

0 个答案:

没有答案