簡體   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