【问题标题】:javascript unit testing variables and code not encapsulated inside functionsjavascript单元测试变量和代码未封装在函数中
【发布时间】:2016-09-09 14:44:27
【问题描述】:

如何为 Angular js 文件中的变量编写单元测试。

fooFactory.spec.js
..
describe('test fooFactory', function(){
   it('test if statement', function(){
      expect(?).toBe(?);
      // how to write a test to pass values to testVar
      // testVar runs before I can assign value to it.
      // even if I have setters and getters how can I retest the if statement
   });
});
..

fooFactory.js
(function () {
   angular.module('MyApp').factory('fooFactory', fooFactory);
   function fooFactory(someOtherFile){
      var testVar = someOtherFile.someOtherfunc;

      if(testVar ){
        // want to test this code. has 10 line of code
      }
      ...  
      function foo(){
        //does something and I can test this
      }
      ...
      return {
         foo:foo
      }
  }
})();

如何在 if 语句运行之前为 testVar 赋值

if(testVar ){
     // how do I test this code?
  }

我是否应该将整个 if 封装在一个函数中并通过 return 传递。

  bar();
  function bar(data){
     if(data){
        testVar = data;
     }
     if(testVar ){
        // how do I test this code?
     }
  }
  return {
   foo: foo,
   bar: bar
  }

有没有更好的方法来做到这一点。 或者js文件首先应该有setter和getter。谢谢

【问题讨论】:

  • 这取决于你在if (testVar) {里面有什么
  • @jcubic sry 混淆,我实际上希望能够将一个值传递给 testVar 以便可以测试里面的代码。

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


【解决方案1】:

您需要在创建fooFactory 时将someOtherFile(如果我理解正确的话,也就是服务)注入到fooFactory 中。

如果您想完全模拟 someOtherFile,请在测试中使用类似的内容

describe('test fooFactory', function(){
    var fooFactory;
    beforeEach(function(){
        fooFactory = new FooFactory(
            { someOtherfunc: function() { return true; } }
        );
        stateChangeCallback = $rootScope.$on.calls.first().args[1];
    });

    it('test if statement', function(){
       expect(fooFactory).toBe(?);
       // how to write a test to pass values to testVar
       // testVar runs before I can assign value to it.
       // even if I have setters and getters how can I retest the if statement
    });
});

但是,如果您需要 someOtherFile 并且您不想模拟它的所有响应,您可以做的是使用角度依赖注入来注入此服务,然后只在其上模拟 someOtherfunc。这将给出这样的结果:

describe('test fooFactory', function(){
    var fooFactory;
    var someOtherFile;

    beforeEach(inject(function (
        _someOtherFile_
    ) {
        someOtherFile = _someOtherFile_;
        fooFactory = new FooFactory(
            someOtherFile
        );
    }));

    it('test if statement', function(){
       spyOn(someOtherFile, 'someOtherfunc').and.returnValue(true);
       expect(?).toBe(?);
       // how to write a test to pass values to testVar
       // testVar runs before I can assign value to it.
       // even if I have setters and getters how can I retest the if statement
    });
});

【讨论】:

  • 谢谢,如果我关心我从 someOtherfunc 获得的值,这将是有意义的,但如果我不关心,只是想将“testVar”的值设置为某个随机值。你认为在那种情况下我需要有 setter 并在 beforeEach 中调用它吗?
  • 我不明白,如果 testVar 不等于 true,您无法在 if no 中测试您的代码?
【解决方案2】:

您无法测试工厂外无法访问的函数/变量。

正确的做法是公开它。但请注意,您不应该仅仅为了使其可测试而公开所有内容。您应该真正考虑为该函数/变量添加测试是否会真正为您的应用程序增加价值。

【讨论】:

  • 我同意,如果它没有意义,那么可能不需要它。
  • 这就是精神! (Y)
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 2011-05-05
相关资源
最近更新 更多