【问题标题】:AngularJS / Karma testing: beforeEach not executedAngularJS / Karma 测试:beforeEach 未执行
【发布时间】:2015-07-05 23:11:25
【问题描述】:

我正在为 AngularJS 开发一些 TDD(完全是另一个故事)并且遇到了我的 beforeEach 调用显然没有被执行的情况。我将其简化为以下示例。

console.log 消息在 beforeEach 中的事实证明了这一点,并且它都出现了:

describe('userApp', function(){ 
  beforeEach( function(){ 
    console.log("in beforeEach...");
  }); 

  it('should be able to log something', function(){ 
    console.log("in it...");
  }); 
});

这不起作用,因为 beforeEach 中的 console.log 消息没有显示,并且在尝试 $log.info 时失败并抛出错误消息:TypeError: Cannot read property 'info' of undefined

describe('userApp', function(){ 
  var $log;
  beforeEach(module('userApp', function($provide) {
    console.log("in beforeEach...");
    // Output messages
    $provide.value('$log', console);
  })); 
  it('should be able to log something', function(){ 
    console.log("in it...");
    $log.info("Using $log for logging...");
  }); 
});

我正在使用 Angular 1.3.15、karma 0.12.31、jasmine 2.3.4。可能我忽略了一些明显的东西......

编辑:Michael Radionov 的解释很有帮助;但是,我不明白为什么这个修改后的代码仍然会抛出同样的错误。

describe('userApp', function(){ 
  console.log("starting TEST3");   <=== this prints
  var $log;
  beforeEach(function() {
    console.log("TEST3: in beforeEach...");   <=== this prints
    module('userApp', function($provide, _$log_) {
      $log = _$log_;
      console.log("TEST3: in beforeEach/module...");   <=== never executed
      // Output messages
      $provide.value('$log', console);
      $log.info("TEST3: calling $log in beforeEach...");
    })
  }); 
  it('should be able to log something', function(){ 
    console.log("TEST3: in it...");
    $log.info("TEST3: Using $log for logging...");  <=== $log undefined err
  }); 
});

此外,“module('userApp'...”中的代码似乎从未执行过...?

【问题讨论】:

    标签: angularjs tdd karma-jasmine


    【解决方案1】:

    没有显示您的日志消息console.log("in beforeEach..."); 的原因是因为它实际上不在beforeEach 内部,而是在作为参数传递给module(..) 的匿名函数内部,该参数被角度认为是模块-嘲笑。这个模块只会在注入发生时执行,同时你会收到一条日志消息in beforeEach...,但你的测试中没有任何注入,所以它永远不会发生。 beforeEach 无论如何都会触发,您只是没有将console.log 放在正确的位置;它会起作用的:

    beforeEach(function () {
    
      console.log("in beforeEach...");
    
      module('userApp', function($provide) {
        // Output messages
        $provide.value('$log', console);
      });
    
    });
    

    您似乎忘记将模拟的$log 注入测试套件,您的$log 变量永远不会获得任何值,因此它在错误状态下保持未定义。

    describe('userApp', function(){ 
    
      var $log;
    
      beforeEach(function () {
        console.log("in beforeEach...");
    
        module('userApp', function($provide) {
          // Output messages
          $provide.value('$log', console);
        });
    
        // getting an instance of mocked service to use in a test suite
        inject(function (_$log_) {
          $log = _$log_;
        });
    
      }); 
    
      it('should be able to log something', function(){ 
        console.log("in it...");
        $log.info("Using $log for logging...");
      }); 
    
    });
    

    见小偷:http://plnkr.co/edit/EirNEthh4CXdBSDAeqOE?p=preview

    文档:

    【讨论】:

    • 谢谢,迈克尔...这开始有所帮助。我将使用另一个似乎应该可以工作的示例来更新帖子。听起来好像——即使 beforeEach() 都被执行了,但它们里面的 module() 代码不一定会同时执行?
    • 在您的更新中,您尝试使用module() 注入_$log_,但它不会起作用。 module() 仅用于注册将在您调用inject() 时执行的模块。注入是对注入器的工作。如果您在每个之前在这里调用inject(),它可能被视为“同时”。在我的示例中,我已将 inject 移至相同的 beforeEach 以使其更清楚
    • 谢谢,迈克尔;你已经很好地解释了这一点。然而,这就是 Angular 开始变得疯狂的地方,IMO。如果我先放“注入”,然后是“模块”语句,那么我会得到“注入器已经创建,无法注册模块!”。在stackoverflow.com/questions/24900067/… 已经有关于SO 的讨论,有许多不同的方法......请注意@gilamarn 对答案的争论。似乎在 Angular 中进行测试非常挑剔。
    • 我想知道为什么你需要在module之前inject。试着这样看:module 像在真实应用程序中一样注册您的模块/服务/工厂/控制器; inject - 有点启动这个应用程序。如果您先调用inject(意味着您的应用程序已经启动),您将无法注册新模块并再次调用inject(再次启动应用程序)。这同样适用于测试工作流程。这个例子非常广泛,但可能有助于理解。
    猜你喜欢
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 2016-10-06
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多