Unit testing 测试使用Jasmine调用承诺的范围函数

Unit testing 测试使用Jasmine调用承诺的范围函数,unit-testing,jasmine,karma-jasmine,deferred,Unit Testing,Jasmine,Karma Jasmine,Deferred,我正在为调用承诺的作用域函数编写测试,并尝试访问在承诺解析后设置的一些作用域属性 这基本上是我的控制器功能: $scope.submitNewForm = function (){ Service.createUser($scope.user).then(function(result){ if (result){ $scope.message = 'success'; } else { $scope.mes

我正在为调用承诺的作用域函数编写测试,并尝试访问在承诺解析后设置的一些作用域属性

这基本上是我的控制器功能:

$scope.submitNewForm = function (){
    Service.createUser($scope.user).then(function(result){
        if (result){
            $scope.message = 'success';
        } else {
            $scope.message = 'error';
        }
        $scope.$apply();
    });
};
我非常想测试的是,在调用scope函数之后,是否设置了我的
$scope.message

到目前为止,我已经使用
$q.defer()
进行了一些测试,但没有成功

beforeEach(inject(function ($controller, $rootScope, _Service_, $q) {
    scope = $rootScope.$new();
    Service= _Service_;
    deferred = $q.defer();
    UserController= $controller('UserController', {
        $scope: scope
    });
}));

it('should call Service.createUser and set a message', function(){
    spyOn(Service, 'createUser').and.callFake(function () {
        return deferred.promise;
    });
    scope.submitNewForm();
    scope.$digest();
    expect(scope.message).toBeDefined();
});

你知道我遗漏了什么吗?

你在运行测试时可能会遇到类似的错误

这是因为您只是从您在
Service
createUser
方法上创建的
spy
返回了一个
promise

你能做些什么来修复它? 只需执行一个
延迟。拒绝
延迟。在
spy
中解决
,您将得到要定义的
范围。消息。大概是这样的:

spyOn(Service, 'createUser').and.callFake(function () {
    deferred.resolve('success');
    return deferred.promise;
});
it('should call Service.createUser and set a message', function(){
    scope.submitNewForm();
    scope.$$postDigest(function(){
        scope.$digest();
        expect(scope.message).toBeDefined();
    });
});
还有一件事我想提出。在注入服务和模拟
控制器
对象之前,您应该将所有间谍都放在
块中。这样它们就可以重复使用

更新: 要将更改应用于范围,可以执行以下操作:

spyOn(Service, 'createUser').and.callFake(function () {
    deferred.resolve('success');
    return deferred.promise;
});
it('should call Service.createUser and set a message', function(){
    scope.submitNewForm();
    scope.$$postDigest(function(){
        scope.$digest();
        expect(scope.message).toBeDefined();
    });
});

不确定这是否有效,但这是通常所做的。

运行测试时,您可能会遇到类似的错误

这是因为您只是从您在
Service
createUser
方法上创建的
spy
返回了一个
promise

你能做些什么来修复它? 只需执行一个
延迟。拒绝
延迟。在
spy
中解决
,您将得到要定义的
范围。消息。大概是这样的:

spyOn(Service, 'createUser').and.callFake(function () {
    deferred.resolve('success');
    return deferred.promise;
});
it('should call Service.createUser and set a message', function(){
    scope.submitNewForm();
    scope.$$postDigest(function(){
        scope.$digest();
        expect(scope.message).toBeDefined();
    });
});
还有一件事我想提出。在注入服务和模拟
控制器
对象之前,您应该将所有间谍都放在
块中。这样它们就可以重复使用

更新: 要将更改应用于范围,可以执行以下操作:

spyOn(Service, 'createUser').and.callFake(function () {
    deferred.resolve('success');
    return deferred.promise;
});
it('should call Service.createUser and set a message', function(){
    scope.submitNewForm();
    scope.$$postDigest(function(){
        scope.$digest();
        expect(scope.message).toBeDefined();
    });
});

不确定这是否有效,但这是通常所做的。

感谢Siddharth的回答。我现在遇到了一个
错误:[$rootScope:inprog]$digest已经在进行中了
,这可能是因为我在Promise回调中调用了
$scope.$apply()
,当我去掉它时,它就起作用了。但我需要它来应用我观点中的变化。有什么想法吗?@adolfosrs,如果这解决了你的问题,请标记为答案。谢谢你的回答Siddharth。我现在遇到了一个
错误:[$rootScope:inprog]$digest已经在进行中了
,这可能是因为我在Promise回调中调用了
$scope.$apply()
,当我去掉它时,它就起作用了。但我需要它来应用我观点中的变化。有什么想法吗?@adolfosrs,如果这解决了你的问题,请标记为答案。