Как проверить обратный вызов функции fs.read
Я хочу протестировать следующий код.
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')
});
});
}
}
Мой тестовый код
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);
});
});
});
Поскольку
fs.read
использует обратный вызов, я не могу протестировать функцию как
lastLines
поле еще не заполнено после звонка
setupFile
. я использую
mocha
для тестов.
1 ответ
Вы должны использовать библиотеку-заглушку sinonjs для заглушки
fs.open()
и
fs.read()
методы. Предоставьте им поддельные реализации. Затем вы можете выполнить обратный вызов вручную в своем тестовом примере.
Например
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
:
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);
});
});
результат модульного теста:
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 |
----------|---------|----------|---------|---------|-------------------
исходный код: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/66332328