javascript - AngularJs 单元测试 - 模拟 promise 不执行 "then"

标签 javascript unit-testing angularjs mocking promise

我们正在对我们的 Controller 进行单元测试。我们已经成功地模拟了对 REST 服务层的调用,并验证了它确实被给定的数据调用了。然而,现在我们想在我们的 Controller 中测试 then promise 的执行是否改变了 location.path:

Controller :

(function () {

    app.controller('registerController', ['$scope', '$location', '$ourRestWrapper', function ($scope, $location, $ourRestWrapper) {

    $scope.submitReg = function(){
        // test will execute this
        var promise = $ourRestWrapper.post('user/registration', $scope.register);

        promise.then(function(response) {    
                console.log("success!"); // test never hits here           
                $location.path("/");
        },
            function(error) {
                console.log("error!"); // test never hits here
                $location.path("/error");
            }
        );
    };

$ourRestWrapper.post(url,data) 只是包装 Restangular.all(url).post(data)..

我们的测试:

(function () {

    describe("controller: registerController", function() {

        var scope, location, restMock, controller, q, deferred;

        beforeEach(module("ourModule"));

        beforeEach(function() {
            restMock = {
                post: function(url, model) {
                    console.log("deferring...");
                    deferred = q.defer();    
                    return deferred.promise;
                }
            };
        });

        // init controller for test
        beforeEach(inject(function($controller, $rootScope, $ourRestWrapper, $location, $q){
            scope = $rootScope.$new();
            location = $location;
            q = $q;

            controller = $controller('registerController', {
                $scope: scope, $location: location, $ourRestWrapper: restMock});
        }));

    it('should call REST layer with registration request', function() {
        scope.register = {data:'test'};

        spyOn(restMock, 'post').andCallThrough();

        scope.submitReg();

        deferred.resolve();

        // successfull
        expect(restMock.post).toHaveBeenCalledWith('user/registration',scope.register);
        expect(restMock.post.calls.length).toEqual(1);
        // fail: Expected '' to be '/'.
        expect(location.path()).toBe('/');
    });

在我们的控制台中,我们看到“deferring...”并且前两个期望成功。为什么它不调用 then block (即设置位置)?

最佳答案

缓存$rootscope当你从注入(inject)器中得到它并调用 $rootScope.$apply() 时对象在 deferred.resolve() 之后立即.

关于javascript - AngularJs 单元测试 - 模拟 promise 不执行 "then",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18916348/

相关文章:

java - java 中的 .isEqualTo 与 .equals

javascript - 使用 $digest angularJS 进行无限循环

javascript - AngularJS - ui.router - 如何在动态添加后重定向到所需状态?

javascript - 关闭嵌入在模式窗口中的youtube播放器

c# - 在 WCF 中捕获 InvalidDataContractException 的单元测试

javascript - 对象 JavaScript,无法读取未定义的属性...之前已读取

android - 即使未调用该方法,Mockito never() 也会被调用吗?

javascript - Angular JS 和 jQuery UI 自动完成功能

javascript - 如何在事件而不是页面加载时加载某些内容

javascript - Node 以编程方式设置导入模块不可用的进程环境变量