简体   繁体   English

如何测试 fs.read function 回调

[英]How to test the fs.read function callback

I want to test the following code.我想测试以下代码。

class Tailer {

  constructor(logFilePath) {
    this.logFilePath = logFilePath;
    this.seekFrom = 0;
    this.lastLines = [];
  }

  setupFile(newlinepointer) {
    var bytesToRead = this.fileSizeInBytes - newlinepointer
    fs.open(this.logFilePath, 'r', (errOpen, fd) => {
      fs.read(fd, Buffer.alloc(bytesToRead), 0, bytesToRead, newlinepointer, (errRead, bytesRead, buffer) => {
        var data = buffer.toString('utf8')
        this.lastLines = data.split('\n')        
      });
    });
  }
}

My test code is我的测试代码是

describe("tailer", function() {
  describe("setupFile", function() {
    it("should fill last 10 lines from given pointer", function() {
      let tailer = new Tailer('test/test.log', (data) => {})
      tailer.setupFile(5)
      assert.equal(tailer.lastLines.length, 10);
    });
  });
});

As the fs.read is using a callback, I am unable to test the setupFile function as the lastLines field is not yet filled after calling setupFile .由于fs.read正在使用回调,我无法测试setupFile function 因为调用setupFilelastLines字段尚未填充。 I am using mocha for tests.我正在使用mocha进行测试。

You should use sinonjs stub library to stub fs.open() and fs.read() methods.您应该使用sinonjs存根库来存根fs.open()fs.read()方法。 Provide fake implementations for them.为他们提供虚假的实现。 Then you can execute the callback manually in your test case.然后您可以在测试用例中手动执行回调。

Eg例如

index.js : index.js

import fs from 'fs';

export class Tailer {
  logFilePath;
  seekFrom;
  lastLines;
  fileSizeInBytes;

  constructor(logFilePath) {
    this.logFilePath = logFilePath;
    this.seekFrom = 0;
    this.lastLines = [];
    this.fileSizeInBytes = 100;
  }

  setupFile(newlinepointer) {
    var bytesToRead = this.fileSizeInBytes - newlinepointer;
    fs.open(this.logFilePath, 'r', (errOpen, fd) => {
      fs.read(fd, Buffer.alloc(bytesToRead), 0, bytesToRead, newlinepointer, (errRead, bytesRead, buffer) => {
        var data = buffer.toString('utf8');
        this.lastLines = data.split('\n');
      });
    });
  }
}

index.test.js : index.test.js

import { Tailer } from './';
import fs from 'fs';
import sinon from 'sinon';
import { expect } from 'chai';

describe('66332328', () => {
  it('should pass', () => {
    const openStub = sinon.stub(fs, 'open').callsFake((filepath, flags, callback) => {
      callback(null, 1);
    });
    const readStub = sinon.stub(fs, 'read').callsFake((fd, buffer, offset, length, position, callback) => {
      callback && callback(null, 100, Buffer.from('teresa teng\nbest singer'));
    });

    const tailer = new Tailer('./test.text');
    tailer.setupFile(50);
    expect(tailer.lastLines).to.be.deep.equal(['teresa teng', 'best singer']);
    sinon.assert.calledWithExactly(openStub, './test.text', 'r', sinon.match.func);
    sinon.assert.calledWithExactly(readStub, 1, Buffer.alloc(50), 0, 50, 50, sinon.match.func);
  });
});

unit test result:单元测试结果:

  66332328
    ✓ should pass


  1 passing (6ms)

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

source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/66332328源代码: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/66332328

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM