我正在尝试测试类,因此我在类core
中拥有调用另一个方法getDrugsByName
的方法。我已经编写了将调用core
的单元测试,然后它还应该调用存根方法getDrugByName
。出于某种原因,下面的测试通过了,但是代码覆盖率未显示内核内部覆盖的代码。任何想法什么实现错误以及如何对嵌套方法进行存根。
DrugPriceApi.node.ts
export class DrugPriceApi extends Types.ModuleBase<DrugPriceParam, DrugPriceResultSet[]> {
core(args: DrugPriceParam, requestMethod: Interface.Core.RequestMethod, _dependencies: any): Promise<any> {
this._dependencies = _dependencies;
return new Promise<any>((resolve: Function, reject: Function) => {
if (!_.isEmpty(args.drugName)) {
let drugSearchParam: any = _.cloneDeep(args);
drugSearchParam.searchText = args.drugName;
this.getDrugsByName(drugSearchParam, requestMethod).then((response: any) => {
if (response.header.statusCode === '0000' && _.has(response, 'detail.drugDetailsList.drug')) {
let drugObject = response.detail.drugDetailsList;
let drugFound: boolean = false;
drugObject.drug = Array.isArray(drugObject.drug) ? drugObject.drug : [drugObject.drug];
drugObject.drug.forEach((item: any) => {
if (!drugFound) {
drugFound = ((item.mailDrug && item.mailDrug.ndcId === args.ndcId) || (item.retailDrug && item.retailDrug.ndcId === args.ndcId));
}
});
if (!drugFound) {
reject({
statusDesc: "NDCID does not belong to the Drug Name provided.",
statusCode: "5000",
refId: response.header.refId
});
} else {
this.getDrugPrice(args, drugObject, requestMethod, resolve, reject, this.Handler);
}
}
}).catch((_err: any) => {
reject({
statusCode: '9999',
refId: args.refId,
statusDesc: _err.statusDesc
});
});
}
});
}
}
function getDrugsByName () {
// return Response after making backend call
}
DrugPriceApi.node.spec.ts
import { } from 'jasmine';
import { DrugPriceParam } from "./DrugPriceApi.interface";
import { DrugPriceApi } from "./DrugPriceApi.node";
import sinon from "sinon";
describe("DrugPriceApi", () => {
let stubbedHttp:any;
const successResponse = {
"details": {
"drugDetailsList": {
"drug": [{
"mailDrug": {
"ndcId": "71015523"
},
"drugForm": "Tab"
}]
}
},
"header": {
"statusDesc": "Success",
"statusCode": "0000"
}
};
beforeEach(function() {
// Below are the modules that are called by GetRxHistoryDetails
// since this is a unit test, these modules should not be tested
// these stubs will stop the real modules from executing
stubbedHttp = sandbox.createStubInstance(HttpRequest);
stubbedHttp.makeRequest.callsFake(function() {
return new Promise<any>((resolve) => {
resolve(successResponse);
});
});
});
it("should call Core", function (done) {
let param = {
tokenId: '123',
appName: 'CMK_WEB',
refId: '123'
} as DrugPriceParam;
param.drugName = 'ACITRETIN';
let mockHttp: any;
let _dependencies: any;
let Service = DrugPriceApi.prototype;
spyOn(Service, 'core').and.callFake(() => {
return {
getDrugsByName: function() {
Promise.resolve(stubbedHttp);
}
}
});
Service.core.call(param,mockHttp,_dependencies);
expect(Service.core).toHaveBeenCalled();
done();
});
};
您的代码覆盖率向您显示了测试中真正拥有的东西,老实说,您不是在测试core
函数,甚至没有被调用,该函数可能充满错误,并且您的测试赢得了甚至都没有注意到。您要调用和测试的是在spyOn(Service, 'core').and.callFake
行中创建的存根函数,该行将完全覆盖原始core
函数。例如,您需要模拟的是getDrugsByName
函数,但是,如果它具有大量的业务逻辑,则还需要考虑为该函数编写测试。
所以,请像这样更改您的测试
it("should call Core", function (done) {
let param = {
tokenId: '123',
appName: 'CMK_WEB',
refId: '123'
} as DrugPriceParam;
param.drugName = 'ACITRETIN';
let mockHttp: any;
let _dependencies: any;
let Service = DrugPriceApi.prototype;
// spyOn "core" using "callThrough" to track all calls to it but
// delegate to the actual implementation.
spyOn(Service, 'core').and.callThrough();
// spyOn "getDrugsByName" using "returnValue"
spyOn(Service, 'getDrugsByName').and.returnValue(Promise.resolve(stubbedHttp));
Service.core.call(param,mockHttp,_dependencies);
expect(Service.core).toHaveBeenCalled();
done();
});
};
[请注意,使用spyOn(Service, 'core').and.callThrough();
跟踪对它的所有调用,但委托给实际的实现。这些将为您提供该功能的完整代码覆盖。
简单的更改将带您进入下一步。但让我列出一些细节
stubbedHttp
不是getDrugsByName
应该返回的内容。您可能需要调整它。mockHttp
为未定义,您将其作为参数传递给core
。注意错误。_dependencies
为未定义,您将其作为参数传递给core
。注意错误。希望有帮助