在Jasmine/node.js中测试独立的JS文件



我有一个独立的JavaScript文件,cachebustinginterceptor.js in node.js应用中。它是一种以工厂模式的服务,该应用程序在应用程序保存时由app.js调用。

/** 
* Intercept the http request 
* If the config.url is from upload or templates and is a html file
* append the cacheBusting Param
* If the template url has query param exisitng
* append &_dt=epochtime else append ?_dt=epochtime
*/
var cacheBustingInterceptor = {
CacheBustingService: CacheBustingServiceFactory
};
function CacheBustingServiceFactory() {
function CacheBustingService() {}
var possibleHtmlPaths = ['templates', 'upload'];
CacheBustingService.prototype.appendCacheBustingParam = function(templateUrl) {
    for (var index = 0; index != possibleHtmlPaths.length; index++) {
        // check if the url has is .html and from upload and templates
        var addCacheBusting = templateUrl.indexOf(possibleHtmlPaths[index]) != - 1 && 
            templateUrl.indexOf('.html') != - 1;
        var hasQueryParams = templateUrl.indexOf('?') != -1;
        if (addCacheBusting) {
            if (hasQueryParams) {
                return templateUrl + window.appendCacheBustingParam;
            } else {
                return templateUrl + window.cacheBustingParam;
            }
        } 
    }
    return templateUrl;
};
CacheBustingService.prototype.interceptRequest = function() {
    var _this = this;
    var cacheBuster = {
        request: function (config) {
            config.url = _this.appendCacheBustingParam(config.url);
            return config;
        }
    }
    return cacheBuster;
}
return CacheBustingService;

}

我们调用的方式是通过在配置中的app.js添加一个注射器,然后将工厂推到配置。

喜欢,

   app. config([''$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('templateCacheBustingInjector');
  app.factory('templateCacheBustingInjector', ['$injector', function 
    ($injector) {
    var CacheBustingService = 
         $injector.invoke(cacheBustingInterceptor.CacheBustingService);
         var cacheBustingService = new CacheBustingService();
    return cacheBustingService.interceptRequest();
  }]);

现在这一切都很好,但是我想单元测试CachebustingInterceptor.js中的" appendCacheBustingParam"方法,并用尽了想法来从茉莉单元测试中调用它

事情累了:1.调用我在app.js中调用的方式,但我遇到服务注入错误或提供商错误2.使用require加载JS文件,但不支持要求,我尝试使用浏览,但是,这也没有帮助。

  require('../main/webapp/media/scripts/cacheBustingInterceptor.js'); 
  fdescribe('Cache Busting Service', function() {
      var cacheBustingService;
       var $injector;
beforeEach((inject(function (_$injector_) {
    $injector = _$injector_;
   $injector.get(cacheBustingInterceptor.CacheBustingService);
    // var CacheBustingService = $injector.invoke(cacheBustingInterceptor.CacheBustingService);
})));
it('Test appendCacheBustingParam', function() {
    cacheBustingService = new CacheBustingService();
    spyOn(cacheBustingService.prototype, 'appendCacheBustingParam');
    expect(cacheBustingService.prototype).toHaveBeenCalled();
});

});

我认为当您说"独自一人"时,这里有一个术语问题。

单元测试测试隔离的代码单位。

Intergration 测试测试隔离单元之间的相互作用

a 单元对您的方法的测试可能是

const mock = {}; // fill with appropriate properties
const result = CacheBustingService
  .prototype
  .appendCacheBustingParam
  .call(mock, someURL);
expect(result).toBe(expectedResult);

单位测试不应要求加密服务。通常应从命令行中的节点中运行单元测试,理想情况下,也没有像npm install那样运行,因为您已经将所有内容都固定了。您的单位测试应进行下一步运行。最好是整个套件,但这可能取决于代码库的大小。

听起来您想要的是集成测试:创建服务实际上是否适当地汇合了所有内容?

在集成测试的情况下,实际构建服务完全有意义,这意味着使用例如使用例如。业力和实际依赖项(不是独立文件)。集成测试的速度较慢/运行较少。

最后一个注释

您的方法不太适合自动化测试,因为它引用了全球范围,并通过窗口进行:

        if (hasQueryParams) {
            return templateUrl + window.appendCacheBustingParam;
        } else {
            return templateUrl + window.cacheBustingParam;
        }

将这些参数改为该方法。

最新更新