ts-mockito-当参数是自定义对象时,存根方法不起作用

时间:2019-03-18 09:55:57

标签: typescript unit-testing mocha sinon

在我的其余架构中,有一个控制器(处理http请求)和一个服务(提供数据的业务逻辑)。

为了测试控制器,我试图对服务进行存根以提供固定的响应,但是我不明白如何对需要自定义对象作为参数的方法进行存根(如果该参数是文字,那么它将起作用)。 / p>

使用自定义对象(Farm)存根不起作用,因为并且我没有从服务方法中收到承诺,这是错误消息:

  

TypeError:无法读取null的属性“ then”   在FarmsController.createFarm(/Users/giovannimarino/Projects/rt-cloud/services/farms/src/farms/farms.controller.ts:17:17)

farms.controller.spec.ts

describe('FarmsController', () => {
  const farmsServiceMock: FarmsService = mock(FarmsService);
  let controller: FarmsController;

  interface TestData {
    farm: Farm;
  }
  let testData: TestData;

  beforeEach(() => {
    reset(farmsServiceMock);
    const farmsServiceMockInstance: FarmsService = instance(farmsServiceMock);
    controller = new FarmsController(farmsServiceMockInstance);

    testData = {
      farm: <Farm> {
        name: 'CattD',
        imageUrl: 'img/farm-123b341.png',
        lang: 'en',
      }
    };
  });

  describe('createFarm function', () => {
    describe('success', () => {
      it('should return HTTP 200 OK', async () => {
        when(farmsServiceMock.createFarm(testData.farm)).thenReturn(Promise.resolve<Farm>(testData.farm));
        const pathParameters: PathParameter = {
          name: 'CattD',
        };
        const bodyRequest: Body = {
          name: testData.farm.name,
          imageUrl: testData.farm.imageUrl,
          lang: testData.farm.lang
        };
        const response: ApiResponseParsed<Farm> = await callSuccess<Farm>(controller.createFarm, pathParameters, bodyRequest);
        expect(response.statusCode).to.equal(HttpStatusCode.Ok);
      });
    });
  });
});

farm.controller.ts

export class FarmsController {
  public constructor(private readonly _service: FarmsService) {
  }

  public createFarm: ApiHandler = (event: ApiEvent, context: ApiContext, callback: ApiCallback): void => {
    if (!event.body) {
      throw new Error('Empty input');
    }
    const input: Farm = <Farm> JSON.parse(event.body);

    this._service.createFarm(input)
      .then((data: Farm) => {
        return ResponseBuilder.created(data, callback);  // tslint:disable-line arrow-return-shorthand
      })
      .catch((error: ErrorResult) => {
        if (error instanceof NotFoundResult) {
          return ResponseBuilder.notFound(error.code, error.description, callback);
        }

        if (error instanceof ForbiddenResult) {
          return ResponseBuilder.forbidden(error.code, error.description, callback);
        }

        return ResponseBuilder.internalServerError(error, callback);
      });
  }
}

farm.service.ts

export class FarmsService {
  public constructor(private readonly _repo: FarmsRepository) {
  }

  public async createFarm(farm: Farm): Promise<Farm> {
    try {
      return this._repo.create(farm);
    } catch (error) {
      throw error;
    }
  }
}

通话成功

export const callSuccess: SuccessCaller = <T>(handler: ApiHandler, 

pathParameters?: PathParameter, body?: Body): Promise<ApiResponseParsed<T>> => {
  // tslint:disable-next-line typedef (Well-known constructor.)
  return new Promise((resolve, reject) => {
    const event: ApiEvent = <ApiEvent> {};
    if (pathParameters) {
      event.pathParameters = pathParameters;
    }
    if (body) {
      event.body = JSON.stringify(body);
    }

    handler(event, <ApiContext> {}, (error?: Error | null | string, result?: ApiResponse): void => {
      if (typeof result === 'undefined') {
        reject('No result was returned by the handler!');
        return;
      }

      const parsedResult: ApiResponseParsed<T> = result as ApiResponseParsed<T>;
      parsedResult.parsedBody = JSON.parse(result.body) as T;
      resolve(parsedResult);
    });
  });
};

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,我使用deepEqual()函数将自定义对象作为参数进行了解决。

import {deepEqual, instance, mock, when} from 'ts-mockito';
...
const myCustomObj = {
  userId: 123
};
when(mockedObj.myMethod(deepEqual(myCustomObj))).thenResolve(myPromise);
...