茉莉花/西宁中有办法对嵌套的功能调用进行存根吗?

问题描述 投票:0回答:1

我正在尝试测试类,因此我在类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();
            });
    };
javascript unit-testing jasmine sinon
1个回答
0
投票

您的代码覆盖率向您显示了测试中真正拥有的东西,老实说,您不是在测试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。注意错误。

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.