【问题标题】:nestjs integration test "Cannot set property "userId' of undefined"Nestjs集成测试“无法设置未定义的属性“userId””
【发布时间】:2021-10-26 23:31:13
【问题描述】:

我开始在 nestjs 中编写端到端测试。连第一个简单的测试都失败了。

describe('Authentication system', () => {
  let app: INestApplication;

  beforeEach(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();
    app = moduleFixture.createNestApplication();
    await app.init();
  });

  it('/(POST)', () => {
    const email = 'khfkjdhsf@hot';
    return request(app.getHttpServer())
      .post('/signup')
      .send({ email, password: 'kasdhfkjdhfkj' })
      .expect(201)
      .then((res) => {
        const { id, email } = res.body;
        expect(id).toBeDefined();
      });
  });
});

这是控制器:

@Post('/signup')
  async createUser(@Body() body: CreateUserDto, @Session() session: any) {
    const user = await this.authService.signUp(body.email, body.password);
    session.userId = user.id;
    return user;
  }

这是 authService.signup:

async signUp(email: string, password: string) {
    const users = await this.usersService.find(email);
    if (users.length) {
      throw new BadRequestException('Email in use');
    }

    const salt = randomBytes(16).toString('hex');
    const hash = (await scrypt(password, salt, 64)) as Buffer;
    const result = salt + '.' + hash.toString('hex');

    const user = await this.usersService.create(email, result);
    return user;
  }

我在 bootstrap() 中使用 cookie-session 进行身份验证:

 app.use(
    cookieSession({
      keys: ['anything'],
      }),
   );

当我向/signup 发送帖子请求时,一切正常。我相信测试逻辑是正确的。我在 stackoverflow 上找不到答案。

我在上述错误下也收到此错误:“Expected 201, 500 Internal Server Error”

【问题讨论】:

  • 你能显示你尝试设置userId的代码吗?
  • 你如何验证用户身份
  • 您确定可以在测试环境中使用快速会话吗?这可能是原因。尝试模拟会话部分。

标签: typescript testing jestjs nestjs integration-testing


【解决方案1】:

您在bootstrap 中设置了cookieSession,但您的bootstrap 与您的测试无关。您需要在测试设置中调用与在bootstrap 中相同的app.use() 以获得中间件奇偶校验,或者将中间件移动到Nest Middleware,这样您以后就不必担心这个了。

@Module(AppModuleMetadata)
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(
      cookieSeesion({
        keys: ['anything'],
      })
    );
  }
}

【讨论】:

    【解决方案2】:

    “app”在app模块中设置,然后像cookie session这样的中间件在bootstrap()中与app连接。我们调用 bootstrap() 并且我们的应用程序开始开发。

    但是,在测试环境中,main.ts 文件不会被执行。我们正在将“app”导入到测试文件中。看beforeEach钩子:

    beforeEach(async () => {
      const moduleFixture: TestingModule = await Test.createTestingModule({
        imports: [AppModule],
      }).compile();
      // this creates the next application out of the AppModule
      app = moduleFixture.createNestApplication();
      await app.init();
    });
    

    如你所见,没有:

    app.use(
        cookieSession({
          keys: ['anything'],
          }),
       );
    

    在测试环境中。 cookie-session 在request 对象上设置“会话”属性,因为您没有在测试环境中设置它,req.session 未定义。这就是为什么您开始“无法设置未定义的属性“userId””。

    您可以通过两种方式解决此问题。第一种方法,创建一个函数并连接中间件:

    export const setupMiddlewares = (app: any) => { 应用程序使用( cookie会话({ 键:['任何东西'], }), ); // 你可以添加所有的中间件或管道 ); };

    
    Then call this in main.ts for development environment
    
    ```js
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      // cookie-session is set
      setupMiddlewares(app);
      await app.listen(3000);
    }
    bootstrap();
    

    在测试文件中:

    beforeEach(async () => {
      const moduleFixture: TestingModule = await Test.createTestingModule({
        imports: [AppModule],
      }).compile();
      app = moduleFixture.createNestApplication();
      // cookie-session is set
      setupMiddlewares(app);
      await app.init();
    });
    

    第二个解决方案是在应用程序模块本身中设置 cookie-session 和所有其他中间件。所以当app模块被执行时,它会自动设置会话中间件。在 app.module.ts 中:

    export class AppModule {
      // this will be called automatically when your app start
      configure(consumer: MiddlewareConsumer) {
        // set up middleware that will run on every incoming request
        consumer
          .apply(
            cookieSession({
              keys: ['anything'],
            }),
            // this means we want to use this middleware for every incoming request
          )
          .forRoutes('*');
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2021-01-22
      • 2020-07-15
      • 2021-11-27
      相关资源
      最近更新 更多