【问题标题】:How to Test AngularJS Jasmine encapsulated promises如何测试 AngularJS Jasmine 封装的 Promise
【发布时间】:2015-09-09 20:04:28
【问题描述】:

也许有人可以帮助我测试一个带有链式承诺的模拟服务。

要测试的工厂

app.factory('factory', [ 'service', function( service ){

 var baz;

 return {
     updateMe: function( updateObj ){

           // do stuff with updateObj

         console.log( updateObj ); 
         // { name: 'Mr. Nobody', _id: '1', _rev: '2' }

           return service.save( updateObj )
               .then( function( result ) {

         console.log( result ); 
         // { name: 'Mr. Foo', _id: '1', _rev: '1' } but should be 
         // { name: 'Mr. Nobody', _id: '1', _rev: '2' }

                   return service.get( result.id )
                        .then( function( getResult ){

                             // do stuff with getResult
                             var index = baz
                                           .map( function(e) { return e.doc._id; } )
                                           .indexOf( getResult._id );

                             baz.splice(index, 1);
                             baz.splice(index, 0, {doc:getResult});

                        });

                });
      },
     saveMe: function( saveObj ){

           // do stuff with saveObj

           return service.save( saveObj )
               .then( function( result ) {

                         saveObj._rev = result.rev;
                         saveObj = { 'doc': saveObj };

                         baz.push( saveObj );

                });
      }
  };
 }]);

测试和模拟

inject( function ( _$q_, _$rootScope_, _service_) {

     $q = _$q_;
     deferred = $q.defer();
     $rootScope = _$rootScope_;
     service = _service_;

}

spyOn(service, 'save').and.callFake(

     function( saveObj ) {

         console.log( saveObj ); 
         // { name: 'Mr. Foo'} or 
         // { name: 'Mr. Nobody', _id: '1', _rev: '2' }


         // do Stuff
         deferred.resolve( result );
         return deferred.promise;

     }

 );
spyOn(service, 'get').and.callFake(

     function( id ) {

         console.log( id ); 
         // always undefined, why? (resolved)
         // this now returns "1"

         // do Stuff
         deferred.resolve( getResult );
         return deferred.promise;

     }

 );

 describe( 'Me is testing a factory', function ( ) {

     it( 'should update the name of Mr.Foo', function ( ) {

         testObj = { name: 'Mr. Foo' };
         factory.updateMe( testObj );
         $rootScope.$digest();

         console.log( factory.baz ); // { name: 'Mr. Foo', _id: '1', _rev: '1' }

         updateObj = { name: 'Mr. Nobody', _id: '1', _rev: '2' };
         factory.updateMe( updateObj );
         $rootScope.$digest();

         console.log( factory.baz );
         // This should be { name: 'Mr. Nobody', _id: '1', _rev: '2' } 
         // but instead it is { name: 'Mr. Foo', _id: '1', _rev: '1' }

     });

 });

我对使用 Jasmine 进行 Angular 和单元测试非常陌生。我是否误解了有关模拟服务的某些内容,还是我遵循了完全错误的方法?

我更新了工厂和测试,希望能更清楚地了解我的问题。

@Benjamin Gruenbaum,我添加了 return,但这没有帮助

【问题讨论】:

  • 承诺作用于返回值,return 内部承诺
  • 在您的测试文件中,result 和 getResult 初始化为什么?如果结果未初始化为具有 id 字段的对象,这将解释 console.log 中的未定义

标签: angularjs mocking jasmine promise karma-jasmine


【解决方案1】:

我终于自己发现了这个错误,傻我。 deferred 变量需要在每个spyOn(obj, 'method').callFake() 函数中设置。由于变量范围,我总是从以前的 deferred.promise 中获得 deferred.resolve 值。

inject( function ( _$q_, _$rootScope_, _service_) {

    $q = _$q_;
    $rootScope = _$rootScope_;
    service = _service_;
   // deferred = $q.defer(); // don't set the deferred var here!

}

spyOn(service, 'save').and.callFake(
    function( obj ) {

       // do stuff to obj

       deferred = $q.defer(); // this is essential
       deferred.resolve( obj );

       return deferred.promise;

    }
);

spyOn(service, 'get').and.callFake(
    function( id ) {

       // create result var and do stuff

       deferred = $q.defer(); // this is essential
       deferred.resolve( result );

       return deferred.promise;

    }
);

【讨论】:

    猜你喜欢
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多