尽管单元测试失败,但突变体仍保持活动状态

Mutant keep alive although unit test failed

提问人:AkiraNoob 提问时间:11/12/2023 最后编辑:jonrsharpeAkiraNoob 更新时间:11/12/2023 访问量:17

问:

我目前尝试使用 Jest 进行单元测试,尝试使用 Stryker 进行突变测试。我面临着一个突变体一直活着的问题,尽管当我尝试该突变时,我的单元测试至少失败了 1 次测试。有人可以解释一下吗?

我的回购:https://github.com/AkiraNoob/kiem_chung

测试用例:

describe('Given valid payload', () => {
      const spyedRefreshCreate = jest.spyOn(RefreshTokenModel, 'create');
      const spyedRefreshDelete = jest.spyOn(RefreshTokenModel, 'deleteMany');
      const spyedFindUser = jest.spyOn(UserModel, 'findOne');
      const spyedBcryptCompare = jest.spyOn(bcryptCommon, 'bcryptCompareSync');
      it('should return statusCode 200 and data should contain {token, refreshToken} and message is "Login successfully"', async () => {
        const data = {
          token: {
            token: expect.any(String),
            expires: expect.any(String),
          },
          refreshToken: {
            token: expect.any(String),
            expires: expect.any(String),
          },
        };

        await expect(authService.loginWithEmailAndPassword(mockLocalLoginPayload)).resolves.toStrictEqual({
          statusCode: EHttpStatus.OK,
          data,
          message: expect.stringMatching('Login successfully'),
        });

        expect(spyedBcryptCompare).toHaveBeenCalledWith(mockLocalLoginPayload.password, expect.any(String));
        expect(spyedBcryptCompare).toHaveReturnedWith(true);

        expect(spyedFindUser).toHaveBeenCalledWith({
          email: expect.any(String),
        });

        expect(spyedRefreshDelete).toHaveBeenCalledWith({
          userId: expect.any(mongoose.Types.ObjectId),
        });

        return expect(spyedRefreshCreate).toHaveBeenCalledWith({
          userId: expect.any(mongoose.Types.ObjectId),
          refreshToken: expect.any(String),
          expiredAt: expect.any(String),
        });
      });
    });

服务:

loginWithEmailAndPassword: async (
    reqBody: TLocalLoginPayload,
  ): Promise<TServiceResponseType<{ token: TReturnJWTType; refreshToken: TReturnJWTType }>> => {
    const user = await UserModel.findOne({ email: reqBody.email }).select('+password');

    if (!user) {
      throw new AppError(EHttpStatus.BAD_REQUEST, 'Wrong email');
    }

    if (!bcryptCompareSync(reqBody.password, user.password)) {
      throw new AppError(EHttpStatus.BAD_REQUEST, 'Wrong password');
    }

    const userData = {
      id: user._id.toString(),
      email: user.email,
      fullName: user.fullName,
    };

    const token = signJWT(userData);
    const refreshToken = signRefreshJWT(userData);

    await RefreshTokenModel.deleteMany({ userId: new mongoose.Types.ObjectId(userData.id) });

    await RefreshTokenModel.create({
      userId: user._id,
      refreshToken: refreshToken.token,
      expiredAt: refreshToken.expires,
    });

    return {
      data: {
        token,
        refreshToken,
      },
      statusCode: EHttpStatus.OK,
      message: 'Login successfully',
    };
  },

突变体

- await RefreshTokenModel.deleteMany({ userId: new mongoose.Types.ObjectId(userData.id) });
+ await RefreshTokenModel.deleteMany({})

Stryker 环境

我的 Stryker 配置:

{
  "$schema": "./node_modules/@stryker-mutator/core/schema/stryker-schema.json",
  "_comment": "This config was generated using 'stryker init'. Please take a look at: https://stryker-mutator.io/docs/stryker-js/configuration/ for more information.",
  "packageManager": "npm",
  "reporters": ["html", "progress"],
  "testRunner": "jest",
  "testRunner_comment": "Take a look at (missing 'homepage' URL in package.json) for information about the jest plugin.",
  "coverageAnalysis": "perTest",
  "mutate": ["src/**"],
  "ignoreStatic": true,
  "checkers": ["typescript"],
  "tsconfigFile": "tsconfig.json",
  "typescriptChecker": {
    "prioritizePerformanceOverAccuracy": false
  }
}

我的 jest 配置

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/**/*.test.ts'],
  forceExit: true,
  verbose: true,
  clearMocks: true,
  setupFiles: ['<rootDir>/.jest/setEnv.ts'],
  coverageDirectory: 'reports/coverage',
  testTimeout: 5000,
};

还有我当前使用节点 18.18.2 的节点

我已经成功运行了测试,在运行 stryker 之后,我收到突变体还活着,我尝试将该突变体应用于代码本身,但测试失败,因此该突变体有望被杀死,对吗?

Express 单元 jestjs 突变测试 stryker

评论


答: 暂无答案