繁体   English   中英

Controller 使用不同的守卫与 nestJS 进行集成测试

[英]Controller integration testing with nestJS using different guards

我正在尝试使用 NestJs 作为后端框架开发一个应用程序。 目前我正在为控制器编写一些集成测试。

这是我使用 typescript 的第一个项目,我通常使用 Java/Spring,但我想学习并尝试 nestJs。

我使用不同的守卫来访问 rest 端点。 在这种情况下,我有一个AuthGuardRolesGuard

为了使 rest 端点正常工作,我只需在 TestingModuleBuilder 中添加如下内容:

        .overrideGuard(AuthGuard())
        .useValue({ canActivate: () => true })

关键是,是否可以为每个测试定义或覆盖此守卫,以检查如果没有定义守卫或不允许守卫,请求是否应该失败?

我的测试代码如下:

describe('AuthController integration tests', () => {
let userRepository: Repository<User>
let roleRepository: Repository<Role>
let app: INestApplication
beforeAll(async () => {
    const module = await Test.createTestingModule({
        imports: [
            AuthModule,
            TypeOrmModule.forRoot(typeOrmConfigTest),
            PassportModule.register({ defaultStrategy: 'jwt' }),
            JwtModule.register({
                secret: jwtConfig.secret,
                signOptions: {
                    expiresIn: jwtConfig.expiresIn
                }
            })
        ]
    })
        .overrideGuard(AuthGuard())
        .useValue({ canActivate: () => true })
        .overrideGuard(RolesGuard)
        .useValue({ canActivate: () => true })
        .compile()
    app = module.createNestApplication()
    await app.init()

    userRepository = module.get('UserRepository')
    roleRepository = module.get('RoleRepository')

    const initializeDb = async () => {
        const roles = roleRepository.create([
            { name: RoleName.ADMIN },
            { name: RoleName.TEACHER },
            { name: RoleName.STUDENT }
        ])
        await roleRepository.save(roles)
    }

    await initializeDb()
})

afterAll(async () => {
    await roleRepository.query(`DELETE FROM roles;`)
    await app.close()
})

afterEach(async () => {
    await userRepository.query(`DELETE FROM users;`)
})

describe('users/roles (GET)', () => {
    it('should retrieve all available roles', async () => {
        const { body } = await request(app.getHttpServer())
            .get('/users/roles')
            .set('accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(200)

        expect(body).toEqual(
            expect.arrayContaining([
                {
                    id: expect.any(String),
                    name: RoleName.STUDENT
                },
                {
                    id: expect.any(String),
                    name: RoleName.TEACHER
                },
                {
                    id: expect.any(String),
                    name: RoleName.ADMIN
                }
            ])
        )
    })
})

当前的实现不可能立即实现,但是如果您将守卫模拟保存为jest模拟,它应该是可能的。 像这样的东西

describe('Controller Integration Testing', () => {
  let app: INestApplication;
  const canActivate = jest.fn(() => true);

  beforeEach(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    })
      .overrideGuard(TestGuard)
      .useValue({ canActivate })
      .compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  it('/ (GET)', () => {
    return request(app.getHttpServer())
      .get('/')
      .expect(200)
      .expect('Hello World!');
  });
  it('/ (GET) Fail guard', () => {
    canActivate.mockReturnValueOnce(false);
    return request(app.getHttpServer())
      .get('/')
      .expect(403);
  });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM