如何在 angular 个控制器中测试本地功能?

How to test local functions within angular controllers?

假设我有一个像这样的控制器:

angular
    .module("app", [])
    .controller("NewsFeedController", [
        "$scope",
        "NewsFeedService",
        function ($scope, NewsFeedService) {
            $scope.news = [
                { stamp: 1 },
                { stamp: 9 },
                { stamp: 0 }
            ];

            $scope.onScroll = function () {
                /*
                    might do some stuff like debouncing, 
                    checking if there's news left to load, 
                    check for user's role, whatever. 
                */

                var oldestStamp = getOldestNews().stamp;
                NewsFeedService.getOlderThan(oldestStamp);

                /* handle the request, append the result, ... */
            };

            function getOldestNews () {
                /* code supposed to return the oldest news */
            }
        }
    ]);

getOldestNews 被声明为局部函数,因为没有必要在 $scope.

中公开它

我该如何处理?我怎样才能真正测试这个功能?

describe("NewsFeedController", function () {
    beforeEach(module("app"));

    var $controller, $scope, controller;

    beforeEach(inject(function (_$controller_) {
        $controller = _$controller_;
        $scope      = {};
        controller  = $controller("NewsFeedController", { $scope: $scope });
    }));

    it("should return the oldest news", function () {
        // How do I test getOldestNews?
    });
});

顺便说一下,如果该解决方案也适用于服务和指令中的本地函数,那就太好了。


相关问题:

现在我明白你真正想在代码中做什么了。我认为没有必要测试私有函数,因为它没有包含足够的逻辑。我建议您只在 NewsFeedService 上创建一个间谍来测试是否将正确的数据发送到该服务。

describe("NewsFeedController", function () {

    beforeEach(module("app"));

    var $controller, $scope, controller;
    var newsFeedServiceMock = jasmine.createSpyObj('NewsFeedService', ['getOlderThan']);

    beforeEach(inject(function (_$controller_) {
        $controller = _$controller_;
        $scope      = {};
        controller  = $controller("NewsFeedController", { $scope: $scope, NewsFeedService : newsFeedServiceMock });
    }));

    it("should return the oldest news", function () {
         $scope.news = [
            { stamp: 76 },
            { stamp: 4 },
            { stamp: 83 }
         ];

         $scope.onScroll();

         expect(newsFeedServiceMock.getOlderThan).toHaveBeenCalledWith(83);
    });
});

这样您就可以检查您的 onScroll 方法是否执行了正确的行为,而无需检查私有方法。您只想测试 public 方法,因此您可以灵活地创建私有方法来分离逻辑,而无需更改测试。