我有一个非常简单的用于 SAML 身份验证的 NestJS 防护,它工作得很好
export class SamlAccessGuard extends AuthGuard('saml') implements CanActivate {
private readonly isDevelopment = process.env.environment === 'dev';
async canActivate(context: ExecutionContext): Promise<boolean> {
if (this.isDevelopment) return true;
const request = context.switchToHttp().getRequest<IUserOnRequest>();
try {
if (request.user == null) {
const shouldActivate = (await super.canActivate(context)) as boolean;
await super.logIn(request);
return shouldActivate;
}
return true;
} catch (e) {
throw new UnauthorizedException('No session found');
}
}
}
我有一些单元测试应该让我达到 100% 的覆盖率,但它报告说,我的测试未覆盖带有
await super.logIn(request);
的行!为什么是这样?我认为这是之前那行的东西, await super.canActivate(context);
,似乎只是接管并且不以某种方式返回值。
这是我的测试的基础知识,我还有其他人测试其他环境,但这与我的问题无关
import { UnauthorizedException } from '@nestjs/common';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { getError } from '../../test-helpers/test-helper-functions';
import { createMockRequest, createMockResponse } from '../../test-helpers/test-mocks';
import { SamlAccessGuard } from './saml-access.guard';
describe('SamlAccessGuard', () => {
const OLD_ENV = process.env;
beforeEach(() => {
jest.resetModules();
process.env = { ...OLD_ENV };
});
afterAll(() => { process.env = OLD_ENV; });
it('should ALLOW access in PROD when a user exists', async () => {
process.env.environment = 'prod';
const guard = new SamlAccessGuard();
const req = createMockRequest();
const res = createMockResponse();
req.user = { userId: 1, username: 'john' };
const ctx = new ExecutionContextHost([req, res]);
const canActivate = await guard.canActivate(ctx);
expect(canActivate).toBe(true);
});
it('should DISALLOW access in PROD when a user is missing', async () => {
process.env.environment = 'prod';
const guard = new SamlAccessGuard();
const req = createMockRequest();
const res = createMockResponse();
req.user = undefined;
const ctx = new ExecutionContextHost([req, res]);
const expectedError = await getError(() => guard.canActivate(ctx));
expect(expectedError).toEqual(new UnauthorizedException('No session found'));
});
});
是否可能正在调用
super.canActivate
方法,但没有履行任何承诺?
我不知道这是否是正确的方法,但您可以像这样模拟父方法调用:
const authGuardMock = jest
.spyOn(AuthGuard.prototype, "canActivate")
.mockResolvedValue(true);