【问题标题】:How to drop into a debugger in a Jasmine test?如何在 Jasmine 测试中进入调试器?
【发布时间】:2018-04-22 15:40:01
【问题描述】:

我正在通过在 Exercism.io 上做练习来改进我的 JavaScript;我目前正在处理http://exercism.io/exercises/javascript/leap/readme

到目前为止,我已经像这样写了leap.js

var Year = function (year) {};

Year.prototype.isLeap = function () {
    return (this.year % 4 === 0 && this.year % 100 !== 0) || this.year % 400 === 0
};

module.exports = Year;

Jasmine 测试,leap.spec.js,是

var Year = require('./leap');

describe('Leap year', function () {
  it('is not very common', function () {
    var year = new Year(2015);
    expect(year.isLeap()).toBe(false);
  });

  it('is introduced every 4 years to adjust about a day', function () {
    var year = new Year(2016);
    expect(year.isLeap()).toBe(true);
  });

  it('is skipped every 100 years to remove an extra day', function () {
    var year = new Year(1900);
    expect(year.isLeap()).toBe(false);
  });

  it('is reintroduced every 400 years to adjust another day', function () {
    var year = new Year(2000);
    expect(year.isLeap()).toBe(true);
  });

但是,一些测试仍然失败:

Kurts-MacBook-Pro:leap kurtpeek$ jasmine leap.spec.js
Started
.F.F

Failures:
1) Leap year is introduced every 4 years to adjust about a day
  Message:
    Expected false to be true.
  Stack:
    Error: Expected false to be true.
        at UserContext.<anonymous> (/Users/kurtpeek/exercism/javascript/leap/leap.spec.js:11:27)

2) Leap year is reintroduced every 400 years to adjust another day
  Message:
    Expected false to be true.
  Stack:
    Error: Expected false to be true.
        at UserContext.<anonymous> (/Users/kurtpeek/exercism/javascript/leap/leap.spec.js:21:27)

Ran 4 of 8 specs
4 specs, 2 failures
Finished in 0.009 seconds

奇怪的是,如果我将 returned 的内容复制到 Node REPL 并将 this.year 替换为 2016,我会按预期得到 true

Kurts-MacBook-Pro:leap kurtpeek$ node
> (2016 % 4 === 0 && 2016 % 100 !== 0) || 2016 % 400 === 0
true

我怀疑发生的事情是this.year 不是数字2016,而是之前实例化的Year 的实例year,因此模表达式没有意义。

然而,为了确认这一点,我想检查isLeap 函数范围内的变量。经过一些谷歌搜索后,我尝试安装 jasmine-debugjasmine-node-debug,但是当我尝试运行其中任何一个时(在 return 语句之前插入 debugger; 语句之后)我收到以下错误:

Kurts-MacBook-Pro:leap kurtpeek$ jasmine-node-debug
internal/modules/cjs/loader.js:550
    throw err;
    ^

Error: Cannot find module '_debugger'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:548:15)
    at Function.Module._load (internal/modules/cjs/loader.js:475:25)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/jasmine-node-debug/node_modules/node-inspector/lib/debugger.js:2:16)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)

根据我在https://github.com/angular/protractor/issues/4307 阅读的内容,此错误与 Node.js 团队将用户迁移到新的inspect API 有关 - 基本上,这些包已过时。

有没有其他方法可以通过 Jasmine 测试进入调试器?

【问题讨论】:

    标签: javascript node.js jasmine node-inspector


    【解决方案1】:

    我设法通过运行 node --inspect-brk 和 Jasmine 的 CLI 调用的 jasmine.js 文件来启动调试器:

    Kurts-MacBook-Pro:bin kurtpeek$ node --inspect-brk /usr/local/lib/node_modules/jasmine/bin/jasmine.js ~/exercism/javascript/leap/leap.spec.js
    Debugger listening on ws://127.0.0.1:9229/03d10b73-1d60-4db3-be79-850f7ee4d0d6
    For help see https://nodejs.org/en/docs/inspector
    Debugger attached.
    Started
    

    然后,在 Chrome 浏览器中导航到 chrome://inspect 并点击“继续”后,我能够确定 this.year 确实是 undefined

    然后我通过定义 this.year 来修复测试:

    var Year = function (year) {
        this.year = year;
    };
    
    Year.prototype.isLeap = function () {
        return (this.year % 4 === 0 && this.year % 100 !== 0) || this.year % 400 === 0
    };
    
    module.exports = Year;
    

    现在测试通过了:

    Kurts-MacBook-Pro:bin kurtpeek$ jasmine ~/exercism/javascript/leap/leap.spec.js
    Started
    ....
    
    
    Ran 4 of 8 specs
    4 specs, 0 failures
    Finished in 0.009 seconds
    

    【讨论】:

      【解决方案2】:

      您没有在任何地方设置 this.year

      在函数 isLeap() 中,this.year undefined 因此传递了 falsy 的规范。

      您可以在规范中使用 console.log() 并随时查看其值。它将被打印到终端以及浏览器实例。 你也可以试试dump()

      试试这个:

      var Year = function (year) {
          this.year = year;
      };
      

      您还可以确认 this.year 持有什么数据类型,使用

      expect(this.year).toEqual(jasmine.any(Number));
      

      【讨论】:

      • 我的问题与其说是如何解决这个问题,不如说是如何进入调试器,以便我可以将所有变量放在我的指尖,并在未来更快地解决这些问题。
      • 有点跑题了不是吗?
      猜你喜欢
      • 1970-01-01
      • 2016-09-14
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 2013-04-19
      • 2019-02-17
      • 1970-01-01
      • 2017-04-14
      相关资源
      最近更新 更多