如何在 Express Jest 测试中清理/重置 redis-mock?

How to clean-up / reset redis-mock in an Express Jest test?

我有一个应用程序可以统计 url 的访问次数。计数是在 Redis 中完成的。我正在使用 redis-mock 模拟内存中的 INCR 之类的命令。

以下测试访问页面 3 次并期望响应对象将 current 报告为 3:

let app = require('./app');
const supertest = require("supertest");

jest.mock('redis', () => jest.requireActual('redis-mock'));

/* Preceeded by the exact same test */

it('should report incremented value on multiple requests', (done) => {
    const COUNT = 3;
    const testRequest = function (cb) { supertest(app).get('/test').expect(200, cb) };

    async.series([
      testRequest,
      testRequest,
      testRequest
    ], (err, results) => {
      if (err) console.error(err);

      const lastResponse = _.last(results).body;
      expect(
        lastResponse.current
      ).toBe(COUNT);

      done();
    });

  });

问题是,如果我继续重复使用 app,内部“redis”模拟将在测试之间继续增加。

我可以通过这样做稍微回避一下:

beforeEach(() => {
  app = require('./app');
  jest.resetAllMocks();
  jest.resetModules();
});

覆盖应用程序似乎可以解决问题,但是没有办法在测试之间以某种方式清理“内部”模拟模块吗?

我的猜测是,套件中的其他一些测试以某种方式调用了“/test”端点,您可以尝试使用 .only or even trying to run the entire suite serially.[=17 运行 套件的特定部分=]

要回答最初的问题,如果您正在 运行 一个特定的测试用例场景,或者如果您正在尝试 运行 整个套件,那么整个套件必须是独立和一致的,因此您需要清除任何可能实际影响结果的残留物。

所以其实可以用.beforeEach or the .beforeAll methods, provided by Jest in order to "mock" Redis and the .afterAll的方法清关

虚拟实现如下所示:

import redis from "redis";
import redis_mock from "redis-mock";
import request from "supertest";

jest.mock("redis", () => jest.requireActual("redis-mock"));

// Client to be used for manually resetting the mocked redis database
const redisClient = redis.createClient();

// Sometimes order matters, since we want to setup the mock
// and boot the app afterwards
import app from "./app";

const COUNT = 3;
const testRequest = () => supertest(app).get("/test");

describe("testing", () => {
  afterAll((done) => {
    // Reset the mock after the tests are done
    jest.clearAllMocks();
    // You can also flush the mocked database here if neeeded and close the client
    redisClient.flushall(done);
    // Alternatively, you can also delete the key as
    redisClient.del("test", done);
    redisClient.quit(done);
  });

  it("dummy test to run", () => {
    expect(true).toBe(true);
  });

  it("the actual test", async () => {
    let last;
    // Run the requests in serial
    for (let i = 0; i < COUNT - 1; i++) {
      last = await testRequest();
    }

    // assert the last one
    expect(last.status).toBe(200);
    expect(last.body.current).toBe(COUNT);
  });
});