2013-04-05 89 views
2

我有一个工厂,使用承诺来解析json文件。 它应该只在第一次解析该文件,并在再次调用时返回结果。AngularJS:需要帮助单元测试承诺的工厂

这里是工厂

app.factory('getServerConfig', function ($q, $http, serverConfig) { 

    return function (fileName) { 
    var deferred = $q.defer(); 

    if (serverConfig.loaded) { 
     deferred.resolve("alreadyLoaded"); 
    } else { 
     $http.get(fileName).then(function (result) { 
     serverConfig.setConfig(result.data); 
     deferred.resolve("loaded"); 
     }, function (result) { 
     deferred.reject(); 
     }); 
    } 
    return deferred.promise; 
    }; 
}) 

我如何测试:

it('should say hallo to the World', inject(function(getServerConfig) { 
    var promiseResult; 

    getServerConfig("server-config.json").then(function (result) { 
     promiseResult = result; 
    }); 

    rootScope.$apply(); 
    expect(promiseResult).toBe('loaded'); 
})); 

不幸的是,它看起来喜欢promiseResult永远不会设置。 这里是用代码plunker:http://plnkr.co/edit/uRPCjuUDkqPRAv07G5Nx?p=preview

回答

3

的问题是,$ httpBackend需要一个flush()(看看Flushing HTTP requests),这样你就可以模仿你的测试$http异步行为。

为了解决这个问题,请存储$httpBackend(或再次注入)的引用,并在请求完成后调用$ httpBack.flush()。

看:

it('should say hallo to the World', inject(function(getServerConfig, $httpBackend) { 
    var promiseResult; 

    getServerConfig("server-config.json").then(function (result) { 
    promiseResult = result; 
    }); 

    $httpBackend.flush(); 
    expect(promiseResult).toBe('loaded'); 
})); 

如果你要在你的大部分规格都使用$httpBackend,考虑将其存储在一个局部变量,并将其设置在beforeEach

+0

啊谢谢。我没有使用flush,但在beforeEach函数内部,这就是为什么它不起作用。谢谢! – 2013-04-05 13:40:56

+0

你会如何测试一个依靠这项服务的控制器?谢谢。 – Hcabnettek 2013-05-15 00:42:03

+0

测试您的控制器的最佳方法是嘲笑此服务并返回一个已知的承诺,您可以控制解析时间。如果你不想嘲笑它,只需要调用'$ httpBackend.flush()',并检查控制器是否按照你期望的方式反应。创建一个新的问题(这是关闭这个主题),并发布一些代码,所以我可以帮助你更多。 – 2013-05-15 13:19:11