模拟"os"nodejs 模块问题



我目前在嘲笑 NodeJS 中的"os"模块时遇到了一些困难。 我想模拟模块的"网络接口"函数以返回固定配置。但是,它仍然返回我的机器的接口数据。

我创建了一个小测试用例来隔离问题:something.ts

import * as os from 'os';
export class Something {
getInterfaces(){
return os.networkInterfaces()
}
}

something.spec.ts

import * as chai from 'chai';
import * as os from 'os';
import * as sinon from 'sinon';
import sinonChai from 'sinon-chai';
import { Something } from './something';
import { ImportMock } from 'ts-mock-imports';
const expect = chai.expect;
chai.use(sinonChai);
const ip1 = '192.168.1.114';
const mockedInterfaces = {
en0: [
{
address: 'fe80::3e07:54ff:fe66:f0f8',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6' as 'IPv6',
mac: '3c:07:54:66:f0:f8',
scopeid: 4,
internal: false,
cidr: '::1/128'
},
{
address: ip1,
netmask: '255.255.255.0',
family: 'IPv4' as 'IPv4',
mac: '3c:07:54:66:f0:f8',
internal: false,
cidr: '127.0.0.1/8'
}
]
};
describe('Something', () => {
let sandbox: sinon.SinonSandbox;
let something: Something;
let stub: sinon.SinonStub;
before(() => {
sandbox = sinon.createSandbox();
// sandbox.stub(os, 'networkInterfaces').callsFake(() => {
//     return mockedInterfaces
// });
stub = ImportMock.mockFunction(os, 'networkInterfaces', mockedInterfaces);
something = new Something();
});
after(() => {
sandbox.restore();
stub.restore();
});
it('Returns the mock', () => {
const interfaces = something.getInterfaces();
expect(interfaces).to.deep.equal(mockedInterfaces);
});
});

运行它会产生:


AssertionError: expected { Object (lo, eno2, ...) } to deeply equal { Object (en0) }
<Click to see difference>
at Context.<anonymous> (socket/xml2/something.spec.ts:57:36)

这意味着它列出了我的接口,而不是返回模拟的接口。

我对如何模拟 nodejs 模块一无所知。任何指导都值得赞赏。

下面是单元测试解决方案:

index.ts

import * as os from 'os';
export class Something {
getInterfaces() {
return os.networkInterfaces();
}
}

index.spec.ts

import proxyquire from 'proxyquire';
import sinon from 'sinon';
import { expect } from 'chai';
const ip1 = '192.168.1.114';
const mockedInterfaces = {
en0: [
{
address: 'fe80::3e07:54ff:fe66:f0f8',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6' as 'IPv6',
mac: '3c:07:54:66:f0:f8',
scopeid: 4,
internal: false,
cidr: '::1/128'
},
{
address: ip1,
netmask: '255.255.255.0',
family: 'IPv4' as 'IPv4',
mac: '3c:07:54:66:f0:f8',
internal: false,
cidr: '127.0.0.1/8'
}
]
};
describe('Something', () => {
it('Returns the mock', () => {
const networkInterfacesStub = sinon.stub().returns(mockedInterfaces);
const { Something } = proxyquire('./', {
os: {
networkInterfaces: networkInterfacesStub
}
});
const something = new Something();
const interfaces = something.getInterfaces();
expect(interfaces).to.deep.equal(mockedInterfaces);
expect(networkInterfacesStub.calledOnce).to.be.true;
});
});

100% 覆盖率的单元测试结果:

Something
✓ Returns the mock (190ms)

1 passing (198ms)
---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |      100 |      100 |      100 |      100 |                   |
index.spec.ts |      100 |      100 |      100 |      100 |                   |
index.ts      |      100 |      100 |      100 |      100 |                   |
---------------|----------|----------|----------|----------|-------------------|

源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/57690820

最新更新