在我的rest体系结构中,有一个控制器(处理http请求)和一个服务(提供数据的业务逻辑)。
为了测试控制器,我试图对服务进行存根,以提供固定的响应,但我不明白如何将一个需要自定义对象作为参数的方法存根(如果参数是文字的,它可以工作)。
对于自定义对象(农场),由于无法从服务方法中得到承诺,因此无法使用此选项,这是一个错误:
(/Users/giovannimarino/Projects/rt-cloud/services/farms/src/farms/farms.controller.ts:17:17):TypeError:无法在FarmsController.createFarm FarmsController.createFarm上读取空属性‘at’
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;
}
}
}callSuccess
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);
});
});
};发布于 2019-06-06 03:50:34
我也面临着同样的问题,我通过使用deepEqual()模拟这个方法来解决这个问题,并将我的自定义对象作为参数传递。
import {deepEqual, instance, mock, when} from 'ts-mockito';const myCustomObj = {
userId: 123
};
when(mockedObj.myMethod(deepEqual(myCustomObj))).thenResolve(myPromise);https://stackoverflow.com/questions/55218654
复制相似问题