使用nestjs进行超级测试e2e:请求不是函数

时间:2018-07-05 14:45:19

标签: node.js e2e-testing supertest nestjs

我尝试为我的简单NestJS后端服务引入e2e测试。我提供了一个用sinon模拟的自定义userService和自定义UserRepository。

这是我的 user.e2e-spec.ts 文件:

import * as request from 'supertest';
import * as sinon from 'sinon';
import { Test } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import { UserService } from '../../src/user/user.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from '../../src/user/user.entity';
import { TestUtil } from '../../src/utils/TestUtil';
import { createFakeUser } from '../../src/user/test/userTestUtil';

let sandbox: sinon.SinonSandbox;
let testUtil;

describe('User', () => {
    let app: INestApplication;
    const fakeUser = createFakeUser();
    const userService = { findOne: () => fakeUser };

    beforeAll(async () => {
        sandbox = sinon.createSandbox();
        testUtil = new TestUtil(sandbox);
        const module = await Test.createTestingModule({
            providers: [
                {
                    provide: UserService,
                    useValue: userService,
                },
                {
                    provide: getRepositoryToken(User),
                    useValue: testUtil.getMockRepository().object,
                },
            ],
        }).compile();

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

    it(`/GET user`, () => {
        return request(app.getHttpServer())
            .get('/user/:id')
            .expect(200)
            .expect({
                data: userService.findOne(),
            });
    });

    afterAll(async () => {
        await app.close();
    });
});

这是我的 user.controller.ts

import { ApiBearerAuth, ApiUseTags } from '@nestjs/swagger';
import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from './user.service';
import { User } from './user.entity';

@ApiUseTags('Users')
@ApiBearerAuth()
@Controller('user')
export class UserController {
    constructor(private readonly userService: UserService) {}

    @Get('/:id')
    findOne(@Param('id') id: number): Promise<User> {
        return this.userService.find(id);
    }
}

我用相同的模式编写了一堆单元测试,并且可以正常工作。不知道这个e2e超级测试怎么了。

感谢您的帮助!

更新: 这是我收到的错误消息:

TypeError: request is not a function
    at Object.it (/Users/florian/Development/Houzy/nestjs-backend/e2e/user/user.e2e-spec.ts:40:16)
    at Object.asyncFn (/Users/florian/Development/Houzy/nestjs-backend/node_modules/jest-jasmine2/build/jasmine_async.js:124:345)
    at resolve (/Users/florian/Development/Houzy/nestjs-backend/node_modules/jest-jasmine2/build/queue_runner.js:46:12)
    at new Promise (<anonymous>)
    at mapper (/Users/florian/Development/Houzy/nestjs-backend/node_modules/jest-jasmine2/build/queue_runner.js:34:499)
    at promise.then (/Users/florian/Development/Houzy/nestjs-backend/node_modules/jest-jasmine2/build/queue_runner.js:74:39)
    at <anonymous>

1 个答案:

答案 0 :(得分:1)

将请求的导入更改为:

  <div class="issue-table-container">
    <table mat-table [dataSource]="dataSource" class="issue-table"
           matSort matSortActive="created" matSortDisableClear matSortDirection="asc">

      <ng-container matColumnDef="number">
        <th mat-header-cell *matHeaderCellDef>Issue #</th>
        <td mat-cell *matCellDef="let row">{{row.number}}</td>
      </ng-container>

      <ng-container matColumnDef="title">
        <th mat-header-cell *matHeaderCellDef>Title</th>
        <td mat-cell *matCellDef="let row"><b>{{row.title}}</b>
        <button mat-raised-button class="label-button" *ngFor="let label of row.labels" [ngStyle]="setBadgeStyles(label.color)">{{label.name}}</button></td>
      </ng-container>

      <ng-container matColumnDef="created">
        <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
          Created
        </th>
        <td mat-cell *matCellDef="let row">{{row.created_at | date:'shortDate'}}</td>
      </ng-container>

      <ng-container matColumnDef="updated">
        <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
          Updated
        </th>
        <td mat-cell *matCellDef="let row">{{row.updated_at | date:'shortDate'}}</td>
      </ng-container>

      <ng-container matColumnDef="estimate">
        <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
          Estimate
        </th>
        <td mat-cell *matCellDef="let row">{{row.estimate}}</td>
      </ng-container>

      <ng-container matColumnDef="pipeline">
        <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
          Pipeline
        </th>
        <td mat-cell *matCellDef="let row">{{row.pipeline}}</td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
  </div>

在测试中,将:id替换为数字:

import request from 'supertest';

在控制器中:

it(`/GET user`, () => {
        return request(app.getHttpServer())
            .get('/user/1') // pass here id, not a string
            .expect(200)
            .expect({
                data: userService.findOne(),
        });
});

现在应该可以使用。