简体   繁体   中英

Controller integration testing with nestJS using different guards

I am trying to develop an application using NestJs as the backend framework. Currently I am writing some integration tests for the controllers.

This is my first project using typescript, I usually use Java/Spring but I wanted to learn and give nestJs a try.

I use different guards to access rest endpoints. In this case I have an AuthGuard and RolesGuard

To make the rest endpoint work I just add something like this in the TestingModuleBuilder:

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

The point is, is it possible to define or override this guards for each test to check that the request should fail if no guard or not allowed guard is defined?

My code for the test is the following one:

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
                }
            ])
        )
    })
})

It's not immediately possibly with the current implementation, but if you save the guard mock as a jest mock it should be possible. Something like this

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);
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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