nestjs中角色保护文件的测试用例



我不知道如何在nestjs中为guard编写单元测试用例文件。我有下面的Role.guard.ts文件。我必须创建Role.guard.spec.ts文件。有人能帮忙吗?

import { Injectable, CanActivate, ExecutionContext, Logger } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ROLES_KEY } from './roles.decorator';
import { Role } from './role.enum';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
const { user } = context.switchToHttp().getRequest();
if (!user.role) {
Logger.error('User does not have a role set');
return false;
}
if (user.role === Role.Admin) {
return true;
}
if (!Array.isArray(requiredRoles) || !requiredRoles.length) {
// No @Roles() decorator set, deny access as not admin
return false;
}
if (requiredRoles.includes(Role.All)) {
return true;
}
return requiredRoles.includes(user.role);
}
}

我写了下面的代码,但覆盖率问题即将到来。

import { createMock } from '@golevelup/ts-jest';
import { ExecutionContext } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { RolesGuard } from "./roles.guard";
describe('RolesGuard', () => {
let guard: RolesGuard;
let reflector: Reflector;
beforeEach(() => {
reflector = new Reflector();
guard = new RolesGuard(reflector);
});
it('should be defined', () => {
expect(guard).toBeDefined();
});
it('should return false if user does not exist', () => {
reflector.getAllAndOverride = jest.fn().mockReturnValue(true);
const context = createMock<ExecutionContext>();
const canActivate = guard.canActivate(context);
expect(canActivate).toBe(false); 
})
})

下面的线没有被覆盖。

if (user.role === Role.Admin) {
return true;
}
if (!Array.isArray(requiredRoles) || !requiredRoles.length) {
// No @Roles() decorator set, deny access as not admin
return false;
}
if (requiredRoles.includes(Role.All)) {
return true;
}
return requiredRoles.includes(user.role);

编辑1:-

下面的测试用例涵盖了我的部分代码。

it('should return true if user  exist', () => {
reflector.getAllAndOverride = jest.fn().mockReturnValue(true);
const context = createMock<ExecutionContext>({
switchToHttp: () => ({
getRequest: () => ({
user: {
role:'admin'
}
}),
}),
});

const canActivate = guard.canActivate(context);
expect(canActivate).toBe(true); 
})

it('should return false if user does not exist', () => {
reflector.getAllAndOverride = jest.fn().mockReturnValue(true);
const context = createMock<ExecutionContext>({
switchToHttp: () => ({
getRequest: () => ({
user: {
role:'user'
}
}),
}),
});

const canActivate = guard.canActivate(context);
expect(canActivate).toBe(false); 
})

但下面的代码仍然没有被覆盖。

if (requiredRoles.includes(Role.All)) {
return true;
}
return requiredRoles.includes(user.role);
}

森博迪也能帮我吗?

看起来您需要能够适当地构建有效负载,以使您的代码命中。有多种方法可以做到这一点;Nest&quot-y的方法,我们可以尝试一些类似文档告诉我们的东西。请注意,在该链接中,提供的测试实用程序使其更容易模拟。

import { createMock } from '@golevelup/ts-jest';
import { ExecutionContext } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { RolesGuard } from "./roles.guard";
describe('RolesGuard', () => {
let guard: RolesGuard;
let reflector: Reflector
beforeEach(async () => {
reflector = new Reflector();
guard = new RolesGuard(reflector);
});
it('should be defined', () => {
expect(guard).toBeDefined();
});
it('should return false if user does not exist', () => {
reflector.getAllAndOverride = jest.fn().mockReturnValue(true);
const context = createMock<ExecutionContext>();
const canActivate = guard.canActivate(context);
expect(canActivate).toBe(false); 
})
it('should return false if user does exist', () => {
reflector.getAllAndOverride = jest.fn().mockReturnValue(true);
// Mock the "class" type of this so we can get what we want.
// We want to tell it to return an object where role is defined.
const context = createMock<ExecutionContext>({
switchToHttp: () => ({
getRequest: () => ({
user: { role: { /* enter your data here */ }
}),
}),
});
const canActivate = guard.canActivate(context);
expect(canActivate).toBe(false); 
})
})

从这里开始,您的上下文成功地与您想要的内容相结合,第二个测试应该开始显示为覆盖您的其他代码分支。现在,您可以编辑role属性,使其看起来像您想要的样子。请注意,在上面的beforeEach调用中,您应该能够切换到使用测试模块。不过,这并不是详尽无遗的,您可能需要添加额外的测试用例来覆盖其他分支。如果你像我在这里所做的那样,那应该是相对琐碎的。

我在这里所做的有意义吗?通过为对象创建自定义负载,roles属性就出现了,从而允许测试评估其他情况。我直接从golevelup的文档中获得了createMock函数的覆盖。

相关内容

最新更新