如何在 Jasmine 测试中放入调试器?

How to drop into a debugger in a Jasmine test?

我通过在 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 的内容复制到节点 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-debug and jasmine-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 测试进入调试器?

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

在函数 isLeap() 中,this.year 是 undefined 因此通过了 falsy 规范。

You can console.log() inside your spec and see its value any time. It will be printed to the terminal as well as the browser instance. You may try dump() as well.

试试这个:

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

您还可以使用

确认this.year持有的数据类型
expect(this.year).toEqual(jasmine.any(Number));

我设法通过 运行 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 并点击 'continue',我能够确定 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