Shr*_*rma 1 javascript unit-testing jestjs typeorm nestjs
我不确定如何编写guardin的单元测试用例文件nestjs。我有以下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);
}
}
Run Code Online (Sandbox Code Playgroud)
我写了下面的代码,但覆盖率问题即将到来。
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);
})
})
Run Code Online (Sandbox Code Playgroud)
下面的行没有被覆盖。
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);
Run Code Online (Sandbox Code Playgroud)
编辑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);
})
Run Code Online (Sandbox Code Playgroud)
但下面的代码仍然没有被覆盖。
if (requiredRoles.includes(Role.All)) {
return true;
}
return requiredRoles.includes(user.role);
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我吗?
看起来您需要能够适当地制作有效负载,以便您的代码能够被命中。有多种方法可以做到这一点,但是,以“Nest”方式,我们可以尝试像文档告诉我们的那样。请注意,在该链接中提供的测试实用程序使模拟变得更加容易。
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);
})
})
Run Code Online (Sandbox Code Playgroud)
从这里开始,您的上下文已成功地与您想要的任何内容结合在一起,第二个测试应该开始显示为覆盖您的其他代码分支。您现在可以编辑该role属性,使其看起来像您想要的那样。另请注意,在上面的beforeEach调用中,您应该能够切换到使用测试模块。但这并不详尽,您可能需要添加额外的测试用例来覆盖其他分支。如果您按照我在这里所做的操作,那么这应该是相对微不足道的。
我在这里所做的有意义吗?通过为对象制作自定义有效负载,该roles属性就存在,允许测试评估其他情况。createMock我直接从golevelup.
| 归档时间: |
|
| 查看次数: |
1405 次 |
| 最近记录: |