【问题标题】:Testing methods returning promise using jasmine使用茉莉花返回承诺的测试方法
【发布时间】:2015-06-11 11:59:16
【问题描述】:

我正在使用 jasmine & karma 来测试我的 Angular 应用程序。我有如下服务

app.service('demo1', function( $http ){
    this.send = function(){
        return $http({
            url: 'someurl'        
        });
    }
});

使用ngMockE2E 模拟响应。

我的茉莉花规格如下:

describe('Testing asynchronus', function(){
    var demoService;
    beforeEach(function(){
        module('app');
        inject(function( demo1 ){
            demoService = demo1
        });
    });

    it('Should be able to test promise', function(){            
        demoService.send().then(function( data ){
            expect(data.status).toBe(true);
        });
    });    
});

现在的问题是,expect 没有执行。每次都通过测试,无论data.status 的值是多少。我需要有关如何测试这些场景的帮助?提前致谢。

真实代码:

describe("Testing MetaService", function(){

    var _entityMeta_, metaService, scope;

    beforeEach(function(){
        console.log( '---------------------- Starting Meta Service fetchEntityMeta Test ---------------------------' );
        module(APP_MODULE_NAME);

        inject(function(_entityMeta_, _metaService_, $rootScope){
            metaService = _metaService_;
            entityMeta = _entityMeta_;
            scope = $rootScope.$new();
        });
    });

    afterEach(function(){
        console.log( '---------------------- Ending Meta Service fetchEntityMeta Test ---------------------------' );
    });


    // Giving mock data from entityMeta.person as input
    it("Should have a valid structure", function($rootScope){ 

        console.log( '////////////////////////////////////////////' );
        metaService.fetchEntityMeta('person').then(function( data ){
            console.log( data );
            expect(data.type).toBe('object');
            expect(data.properties.length).toBeGreaterThan(0);
            expect(data.definitions.length).toBeGreaterThan(0);            
        });        

    });

});

我收到以下错误:

Error: Timeout - Async callback was not invoked within timeout specified
 by jasmine.DEFAULT_TIMEOUT_INTERVAL.

【问题讨论】:

  • ngMockE2E 用于端到端测试,而不是用于使用 karma 运行的单元测试。你需要告诉 ngMock $httpBackend 做什么。阅读文档:docs.angularjs.org/api/ngMock/service/$httpBackend
  • 我主要关心的是如何测试该方法是否返回一个承诺。除了 ngMock,我还尝试过使用 $q。似乎如果函数返回一个承诺,则“then”回调中的期望块将不会被执行。
  • 您需要调用 $scope.$apply()(或 $rootScope.$apply()),以便在您解决承诺后调用承诺回调。
  • 我的承诺是在服务方法中解决的。看起来如果服务在规范文件的描述块内被模拟和解析,那么这个 $scope.$apply() 可以用来测试它,但在我的例子中,它不起作用。我需要这适用于真正的 api 响应,用于验证 api 的响应
  • 我们在您未显示的代码中找不到错误。发布 REAL 代码,告诉我们您希望它做什么以及它会做什么。

标签: angularjs unit-testing jasmine karma-runner karma-jasmine


【解决方案1】:

尝试添加

beforeEach(module('app'));

在描述下

【讨论】:

  • 糟糕,我在写问题时错过了这一点。顺便说一句,这不是问题。问题是当一个方法返回承诺时,我应该如何测试它?因为按照我的做法,它不起作用。
  • 通常在单元测试中,api调用被模拟而不是测试cz代码不应该依赖于api url响应@YeasinHossain
  • 所以你的意思是,在单元测试中,我可以跳过为依赖于 api 调用的方法编写测试,比如 demo1 服务的 send 方法,对吧?我的想法是,当我的 Web 服务准备就绪并且我的请求将与真正的 api 交互时,我可以运行此测试来验证我的 api 的数据结构。
  • 最好做端到端测试,使用量角器测试角度代码。
【解决方案2】:

如果您使用 Jasmine 2,则传递给 it 的回调参数应该是测试完成时调用的 done 函数。 (如果从不调用测试运行程序,它将超时。)

(参见the official doc here,或one of many blog posts。)

我真的不明白为什么你在这种情况下传递$rootScope,但错误消息看起来像一个抱怨,因为done 函数(这里恰好被命名为$rootScope)还没有被调用。

这可能有效:

// Giving mock data from entityMeta.person as input
it("Should have a valid structure", function(done){ 

    console.log( '////////////////////////////////////////////' );
    metaService.fetchEntityMeta('person').then(function( data ){
        console.log( data );
        expect(data.type).toBe('object');
        expect(data.properties.length).toBeGreaterThan(0);
        expect(data.definitions.length).toBeGreaterThan(0);            
        done();
    }, function (e) {
        // The promise was not resolved, this is most likely an
        // implementation error. Let's fail the test !
        throw new Error(e);
    });        

});

如果从未调用过then 部分,则done 函数也不会调用,您将收到您现在看到的超时错误。

【讨论】:

  • 得到同样的错误。根据茉莉花的文档,我已将 jasmine.DEFAULT_TIMEOUT_INTERVAL 增加到 10000。但仍然无法正常工作。看起来 then 部分没有被调用。就是不明白为什么?
  • 如果问题是 then 部分没有被调用,那么很可能是 metaService 本身的代码存在问题 - 除了您之外,任何人都几乎不可能调试,因为我们不'没有代码......要遵循的一般路径是确保“fetchEntityMeta'实际上返回一个Promise,并且这个Promise really 在某个时候得到解决。您可能想要添加一个then 部分处理错误情况,也许你会得到一些有趣的信息。祝你好运!
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2016-04-02
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多