Angularjs 因果报应/茉莉花-测试;关于;角度JS控制器中的侦听器

Angularjs 因果报应/茉莉花-测试;关于;角度JS控制器中的侦听器,angularjs,jasmine,karma-runner,Angularjs,Jasmine,Karma Runner,我的控制器中有以下代码: angular.element($window).on("resize", function(){ if($scope.getScreenWidth() >= $scope.minScreenWidth){ $scope.showNotification("notificationOne"); } else{ $scope.showNotification("notif

我的控制器中有以下代码:

angular.element($window).on("resize", function(){
        if($scope.getScreenWidth() >= $scope.minScreenWidth){
            $scope.showNotification("notificationOne");
        }
        else{
            $scope.showNotification("notificationTwo");
        }
});
当用户调整浏览器大小时,上面的内容将在其屏幕上显示一条消息。根据屏幕的当前宽度,显示的消息会有所不同


是否有任何地方可以使用Jasmine/Karma测试上述代码?如果没有,我应该如何编写上面的控制器代码段,以便测试功能?

您应该尽量避免控制器内的DOM操作。。。也就是说,您可能可以将resize侦听器放在控制器外部,并使用$rootScope来广播resize。module.run可能是启动它的好地方:

mod.run(function ($window, $rootScope, $timeout) {
    angular.element($window).on("resize", function () {
        //broadcast your event of interest
        $timeout(function () {
            $rootScope.$broadcast("myApp.windowResize");
        }, 0);
    });
});
然后在控制器中,您可以订阅myApp.windowResize事件:

$scope.$on("myApp.windowResize", function () {
    var screenWidth = $scope.getScreenWidth();

    if(screenWidth >= $scope.minScreenWidth){
        $scope.showNotification("notificationOne");
    }
    else{
        $scope.showNotification("notificationTwo");
    }
});

$scope.showNotification = function (msg) {
    $scope.message = msg;
}
从这里开始,从茉莉花/业力测试中播放同样的事件将是微不足道的。您还必须记住,$scope.getScreenWidth可能需要模拟以返回不同的值,以便您可以断言showNotification是使用“notificationOne”还是“Notification2”调用的。例如:

describe("hello controller test", function () {
    var $scope;
    beforeEach(module("myApp"));
    beforeEach(inject(function ($rootScope) {
        $scope = $rootScope.$new();
    }));

    it("should have notificationOne", inject(function($controller, $rootScope) {
        $controller("MainController", {$scope: $scope});

        //mock screen width call: Always return a greater or equal value for notificationOne.
        $scope.getScreenWidth = function () {
            return $scope.minScreenWidth;
        }

        $rootScope.$broadcast("myApp.windowResize");
        $rootScope.$apply();

        expect($scope.message).toBeDefined();
        expect($scope.message).toBe("notificationOne");
    }));
});

下面是演示应用程序的一个示例。

您应该尽量避免在控制器中操纵DOM。。。也就是说,您可能可以将resize侦听器放在控制器外部,并使用$rootScope来广播resize。module.run可能是启动它的好地方:

mod.run(function ($window, $rootScope, $timeout) {
    angular.element($window).on("resize", function () {
        //broadcast your event of interest
        $timeout(function () {
            $rootScope.$broadcast("myApp.windowResize");
        }, 0);
    });
});
然后在控制器中,您可以订阅myApp.windowResize事件:

$scope.$on("myApp.windowResize", function () {
    var screenWidth = $scope.getScreenWidth();

    if(screenWidth >= $scope.minScreenWidth){
        $scope.showNotification("notificationOne");
    }
    else{
        $scope.showNotification("notificationTwo");
    }
});

$scope.showNotification = function (msg) {
    $scope.message = msg;
}
从这里开始,从茉莉花/业力测试中播放同样的事件将是微不足道的。您还必须记住,$scope.getScreenWidth可能需要模拟以返回不同的值,以便您可以断言showNotification是使用“notificationOne”还是“Notification2”调用的。例如:

describe("hello controller test", function () {
    var $scope;
    beforeEach(module("myApp"));
    beforeEach(inject(function ($rootScope) {
        $scope = $rootScope.$new();
    }));

    it("should have notificationOne", inject(function($controller, $rootScope) {
        $controller("MainController", {$scope: $scope});

        //mock screen width call: Always return a greater or equal value for notificationOne.
        $scope.getScreenWidth = function () {
            return $scope.minScreenWidth;
        }

        $rootScope.$broadcast("myApp.windowResize");
        $rootScope.$apply();

        expect($scope.message).toBeDefined();
        expect($scope.message).toBe("notificationOne");
    }));
});

下面是演示应用程序的一个示例。

您应该尽量避免在控制器中操纵DOM。。。也就是说,您可能可以将resize侦听器放在控制器外部,并使用$rootScope来广播resize。module.run可能是启动它的好地方:

mod.run(function ($window, $rootScope, $timeout) {
    angular.element($window).on("resize", function () {
        //broadcast your event of interest
        $timeout(function () {
            $rootScope.$broadcast("myApp.windowResize");
        }, 0);
    });
});
然后在控制器中,您可以订阅myApp.windowResize事件:

$scope.$on("myApp.windowResize", function () {
    var screenWidth = $scope.getScreenWidth();

    if(screenWidth >= $scope.minScreenWidth){
        $scope.showNotification("notificationOne");
    }
    else{
        $scope.showNotification("notificationTwo");
    }
});

$scope.showNotification = function (msg) {
    $scope.message = msg;
}
从这里开始,从茉莉花/业力测试中播放同样的事件将是微不足道的。您还必须记住,$scope.getScreenWidth可能需要模拟以返回不同的值,以便您可以断言showNotification是使用“notificationOne”还是“Notification2”调用的。例如:

describe("hello controller test", function () {
    var $scope;
    beforeEach(module("myApp"));
    beforeEach(inject(function ($rootScope) {
        $scope = $rootScope.$new();
    }));

    it("should have notificationOne", inject(function($controller, $rootScope) {
        $controller("MainController", {$scope: $scope});

        //mock screen width call: Always return a greater or equal value for notificationOne.
        $scope.getScreenWidth = function () {
            return $scope.minScreenWidth;
        }

        $rootScope.$broadcast("myApp.windowResize");
        $rootScope.$apply();

        expect($scope.message).toBeDefined();
        expect($scope.message).toBe("notificationOne");
    }));
});

下面是演示应用程序的一个示例。

您应该尽量避免在控制器中操纵DOM。。。也就是说,您可能可以将resize侦听器放在控制器外部,并使用$rootScope来广播resize。module.run可能是启动它的好地方:

mod.run(function ($window, $rootScope, $timeout) {
    angular.element($window).on("resize", function () {
        //broadcast your event of interest
        $timeout(function () {
            $rootScope.$broadcast("myApp.windowResize");
        }, 0);
    });
});
然后在控制器中,您可以订阅myApp.windowResize事件:

$scope.$on("myApp.windowResize", function () {
    var screenWidth = $scope.getScreenWidth();

    if(screenWidth >= $scope.minScreenWidth){
        $scope.showNotification("notificationOne");
    }
    else{
        $scope.showNotification("notificationTwo");
    }
});

$scope.showNotification = function (msg) {
    $scope.message = msg;
}
从这里开始,从茉莉花/业力测试中播放同样的事件将是微不足道的。您还必须记住,$scope.getScreenWidth可能需要模拟以返回不同的值,以便您可以断言showNotification是使用“notificationOne”还是“Notification2”调用的。例如:

describe("hello controller test", function () {
    var $scope;
    beforeEach(module("myApp"));
    beforeEach(inject(function ($rootScope) {
        $scope = $rootScope.$new();
    }));

    it("should have notificationOne", inject(function($controller, $rootScope) {
        $controller("MainController", {$scope: $scope});

        //mock screen width call: Always return a greater or equal value for notificationOne.
        $scope.getScreenWidth = function () {
            return $scope.minScreenWidth;
        }

        $rootScope.$broadcast("myApp.windowResize");
        $rootScope.$apply();

        expect($scope.message).toBeDefined();
        expect($scope.message).toBe("notificationOne");
    }));
});

这是演示应用程序的一个示例。

这可能是“角度”的方式,但您必须编写更多的代码以遵守“角度”原则,这一事实实际上表明,角度团队应该重新编写此问题和相关问题—只需再编写几行代码—只需模块。运行安装程序。您可能拥有的其余代码;您的控制器正在侦听其他事件。。。同样,您不必遵守这一点,只需订阅控制器中的window.onresize即可-但正如您所知,这会更多地限制测试表面(就像在其他框架中执行特定于UI的操作会限制单元测试的能力一样)。这可能是一种“角度”方式,但是,为了遵守“Angular”原则,您必须编写更多的代码,这一事实实际上表明Angular团队应该重新编写这些代码和相关的问题。只需再编写几行代码,即module.run安装程序。您可能拥有的其余代码;您的控制器正在侦听其他事件。。。同样,您不必遵守这一点,只需订阅控制器中的window.onresize即可-但正如您所知,这会更多地限制测试表面(就像在其他框架中执行特定于UI的操作会限制单元测试的能力一样)。这可能是一种“角度”方式,但是,为了遵守“Angular”原则,您必须编写更多的代码,这一事实实际上表明Angular团队应该重新编写这些代码和相关的问题。只需再编写几行代码,即module.run安装程序。您可能拥有的其余代码;您的控制器正在侦听其他事件。。。同样,您不必遵守这一点,只需订阅控制器中的window.onresize即可-但正如您所知,这会更多地限制测试表面(就像在其他框架中执行特定于UI的操作会限制单元测试的能力一样)。这可能是一种“角度”方式,但是,为了遵守“Angular”原则,您必须编写更多的代码,这一事实实际上表明Angular团队应该重新编写这些代码和相关的问题。只需再编写几行代码,即module.run安装程序。您可能拥有的其余代码;您的控制器正在侦听其他事件。。。同样,您不必遵守这一点,只需订阅控制器中的window.onresize即可——但正如您所知,这会更多地限制测试界面(就像在其他框架中执行特定于UI的操作会限制单元测试的能力一样)。