为什么我不能spyOn()注入服务中的某些功能?

时间:2017-07-24 15:27:56

标签: javascript angularjs typescript jasmine

我正在测试我的一个调用多个服务的组件。我一直在注入服务并使用spyOn()模拟假函数调用。

我的问题是在此服务上调用特定函数会产生错误Error: <spyOn : refreshThings() method does not exist>。对于同一服务中的其他功能,我可以spyOn()就好了。

BasketController取决于ThingService的一些相关代码段:

修改:清理代码

单元测试

describe("BasketController test", () => {
    let $componentController: ng.IComponentControllerService;
    let $scope: ng.IRootScopeService;
    let BasketService;
    let ctrl;
    let ThingService: ThingService;

    // Injections and controller
    beforeEach(() => {
        angular.mock.module("myModule");

        angular.mock.inject(
            (_$componentController_: ng.IComponentControllerService,
                _$rootScope_: ng.IRootScopeService,
                _BasketService_: BasketService,
                _ThingService_: ThingService
            ) => {
                $componentController = _$componentController_;
                $scope = _$rootScope_;
                BasketService = _BasketService_;
                ThingService = _ThingService_;
            }
        );

        ctrl = $componentController('basket',
            {
                '$scope': $scope,
                'BasketService': BasketService,
                'ThingService': ThingService
            }
        );

        spyOn(ThingService, 'refreshThings').and.callFake(() => {
        });
    });

    it('should be testable', () => {
        expect(ctrl).toBeDefined();
    });

控制器

export class BasketController {
    static $inject = ["BasketService", "$state", "AlertService", "$filter", "ThingService"];

    constructor(_BasketService_: BasketService,
        private $state: ng.ui.IStateService,
        private AlertService: AlertService,
        private $filter,
        private ThingService: ThingService) {
            this.BasketService = _BasketService_;
    }

    BasketService: BasketService;
    headerData: Object;
    basketForm: ng.IFormController;
    basket: Basket;
    basketList: Array<Basket>;
    selectAll: boolean;

    toolbarButtons: any;
    columns: [string];
    itemFormatter: any;
    self: any;

    $onInit() {
        // GETs baskets from the service
        this.ThingService.refreshThings();
    }
}

注入服务

export class ThingService {

    static $inject = ["ApiHttpService", "$q", "AlertService", "StatusThingService"];
    currentThing: Thing;
    thingList: Array<Thing>;

    constructor(private ApiHttpService: IHttpService,
        private $q: ng.IQService,
        private AlertService: AlertService,
        private StatusThingService: StatusThingService) {
    }

    $onInit() {
    }

    getThing(href:string) {

        let defer = this.$q.defer();

        this.ApiHttpService.get(href).then(
            (res:GetThing) => {
                defer.resolve(res);
            },
            (res) => {
                defer.reject(res);
            }
        );

        return defer.promise;
    }

    getAllThings() {

        let defer = this.$q.defer();

        this.ApiHttpService.get("/api/Thing").then(
            (res:Array<GetThing>) => {
                defer.resolve(res);
            },
            (res) => {
                defer.reject(res);
            }
        );

        return defer.promise;
    }

    refreshThings() {
        this.thingList = [];

        this.getAllThings().then(
            (res:Array<GetThing>) => {

                for(let getTemp of res) {
                    let thing = new Thing();
                    thing.fromGet(getTemp);
                    this.thingList.push(thing);
                }
            },
            (res) => {
                console.error("Unable to refresh things");
            }
        );
    }

}

Main.module.service("ThingService", ThingService);

再一次,试图窥探refreshThings会导致错误Error: <spyOn> : refreshThings() method does not exist,同时监视服务中的任何其他函数都可以正常工作。

对我来说真的是一个头脑风暴所以非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

我不知道Angular,但是ThingService看起来像构造函数/类,因此您可以尝试监视原型,例如spyOn(ThingService.prototype, 'refreshThings')