使用 Sinon 模拟在构造函数中设置的类属性

爱德华多·鲁索

我正在尝试模拟在构造函数中设置为默认值的类属性

class Files {
  constructor(queueNumber = 0) {
    this.queueNumber = queueNumber;
    this.dir = 'JiraResults';
    if (!fs.existsSync(this.dir)) {
      fs.mkdirSync(this.dir);
    }
  }
  ...
}

构造函数根据dir属性创建目录和文件,对于测试,我想要另一个目录,所以我不需要移动实际目录来运行测试。

我尝试了很多方法来替换该属性,但所有方法都因来自 Sinon 的不同错误而不断失败。

第一次尝试:

const tempDir = 'JiraResults-TEMP';
let stubDir;

describe('Files', () => {
  before(() => {
    stubDir = sinon.stub(Files.prototype.constructor, 'dir').value(tempDir);
  }
  ...
}

有了这个,我得到了错误 TypeError: Cannot stub non-existent own property dir

第二次尝试

const tempDir = 'JiraResults-TEMP';
let stubDir;

describe('Files', () => {
  before(() => {
    stubDir = sinon.stub(Files.prototype, 'dir').value(tempDir);
  }
  ...
}

有了这个,我得到了错误 TypeError: Cannot stub non-existent own property dir

第三次尝试

const tempDir = 'JiraResults-TEMP';
let stubDir;

describe('Files', () => {
  before(() => {
    stubDir = sinon.stub(Files.prototype, 'this').value({
      dir: sinon.stub().returnsThis(tempDir),
    });
  }
  ...
}

有了这个,我得到了错误 TypeError: Cannot stub non-existent own property this


我也尝试过其他事情,但从未达到更换房产的地步。

我查看了 Sinon 文档,但似乎没有一个示例适用于构造函数类。

谁能给我一个关于如何替换此属性的工作示例?

谢谢。

幻灯片p2

您可以dir直接更改属性的值,以便被测方法将使用存根dir.

例如

files.js

class Files {
  constructor(queueNumber = 0) {
    this.queueNumber = queueNumber;
    this.dir = "JiraResults";
  }

  mkdir() {
    console.log("make dir: ", this.dir);
  }
}

module.exports = Files;

files.test.js

const Files = require("./files");
const sinon = require("sinon");

describe("Files", () => {
  it("should use stubbed dir", () => {
    sinon.spy(console, "log");
    const instance = new Files();
    instance.dir = "stubbed dir";
    instance.mkdir();
    sinon.assert.calledWith(console.log, "make dir: ", "stubbed dir");
  });
});

单元测试结果:

Files
make dir:  stubbed dir
    ✓ should use stubbed dir


  1 passing (7ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |      100 |      100 |      100 |      100 |                   |
 files.js      |      100 |      100 |      100 |      100 |                   |
 files.test.js |      100 |      100 |      100 |      100 |                   |
---------------|----------|----------|----------|----------|-------------------|

更新:

我不认为这是可能的。让我们看看下面的例子:

files.js

const fs = require("fs");

class Files {
  constructor(queueNumber = 0) {
    this.queueNumber = queueNumber;
    console.log("before: ", this.dir);
    this.dir = "JiraResults";
    console.log("after: ", this.dir);
    if (!fs.existsSync(this.dir)) {
      fs.mkdirSync(this.dir);
    }
  }
}

Files.prototype.dir = "";

module.exports = Files;

files.test.js

const Files = require("./files");
const sinon = require("sinon");
const fs = require("fs");

describe("Files", () => {
  it("should use stubbed dir to mkdir", () => {
    sinon.stub(fs, "existsSync").returns(false);
    sinon.stub(fs, "mkdirSync");
    sinon.stub(Files.prototype, "dir").value("stubbed dir");
    console.log("stub dir");
    new Files();
    sinon.assert.calledWith(fs.existsSync, "stubbed dir");
    sinon.assert.calledWith(fs.mkdirSync, "stubbed dir");
  });
});

单元测试结果:

  Files
stub dir
before:  stubbed dir
after:  JiraResults
    1) should use stubbed dir to mkdir


  0 passing (13ms)
  1 failing

  1) Files
       should use stubbed dir to mkdir:
     AssertError: expected existsSync to be called with arguments 
JiraResults stubbed dir 
      at Object.fail (node_modules/sinon/lib/sinon/assert.js:106:21)
      at failAssertion (node_modules/sinon/lib/sinon/assert.js:65:16)
      at Object.assert.(anonymous function) [as calledWith] (node_modules/sinon/lib/sinon/assert.js:91:13)
      at Context.it (src/stackoverflow/59303752/files.test.js:1:2345)

我们可以dir在实例化类之前成功地为属性创建一个存根Files但是在我们实例化了类之后Files它将“JiraResults”字符串分配给属性dir,这意味着它将替换stubbed dirto JiraResults

共有三个选项:

  1. 为 property 设置一个默认值dirFiles.prototype.dir = 'JiraResults'(但这取决于您的要求。)
  2. dir作为参数传递Files的构造函数
  3. fs操作提取到类似于原始 anwser 的方法中。

然后,为单元测试制作存根会更容易。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章