How can you mock external dependencies?
See original GitHub issueI am trying to test a logger-service, which uses imports from the node_modules winston
and fs
, and I would like to mock these imports, but I don’t know how. With nest it’s really easy to mock the injected dependencies, but these dependencies are imported, not injected. For normal Node.js modules I use proxyquire to proxy my required node_modules, but that’s not possible with Nest, because the dependencies are imported, not required, and they are imported very early in the process (before the constructor of the service is called).
Here is my logger-service:
import {Component} from '@nestjs/common';
import {Logger, transports} from 'winston';
import * as path from 'path';
import * as fs from 'fs';
import { ConfigService } from '../config/config.service';
require('winston-daily-rotate-file');
@Component()
export class LoggerService {
logger:any;
logFolders:any;
constructor(private config:ConfigService) {
this.logFolders = {base: path.join(__dirname, '..', '..', '..', 'logs')};
this.logFolders.debug = path.join(this.logFolders.base, 'debug');
this.logFolders.exception = path.join(this.logFolders.base, 'debug');
this._createLogFolders();
this.logger = new Logger({
transports: [
new transports.Console({
json: false,
timestamp: true,
level: config.get('debug') ? 'debug' : 'info'
}),
new transports.DailyRotateFile({
filename: path.join(this.logFolders.debug, 'debug.log'),
json: false,
level: 'error',
datePattern: 'yyyy-MM-dd-',
prepend: true
})
],
exceptionHandlers: [
new transports.Console({
json: false,
timestamp: true,
level: config.get('debug') ? 'debug' : 'info'
}),
new transports.DailyRotateFile({
filename: path.join(this.logFolders.exception, 'execeptions.log'),
json: false,
level: 'error',
datePattern: 'yyyy-MM-dd-',
prepend: true
})
],
exitOnError: false
});
}
private _createLogFolders() {
const createDir = dir => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
};
createDir(this.logFolders.base);
createDir(this.logFolders.debug);
createDir(this.logFolders.exception);
}
debug(message:string) {
this.logger.debug(message);
}
info(message:string) {
this.logger.info(message);
}
warn(message:string) {
this.logger.warn(message);
}
error(message:string) {
this.logger.error(message);
}
}
And this is my test:
import {Test} from '@nestjs/testing';
import {TestingModule} from '@nestjs/testing/testing-module';
import {LoggerService, ConfigService} from '../';
import {expect} from 'chai';
import * as sinon from 'sinon';
describe ('LoggerService', () => {
let module: TestingModule;
let service: LoggerService;
let sandbox;
let logStub;
beforeEach(async () => {
sandbox = sinon.sandbox.create();
module = await Test.createTestingModule({
components: [
LoggerService,
ConfigService
]
}).compile();
service = module.get(LoggerService);
});
it('should exist', () => {
expect(service).to.exist;
});
it('should log a debug message', () => {
logStub = sandbox.stub(service.logger, 'debug');
service.debug('someMessage');
expect(logStub).to.have.been.calledWith('someMessage');
});
it('should log a info message', () => {
logStub = sandbox.stub(service.logger, 'info');
service.info('someMessage');
expect(logStub).to.have.been.calledWith('someMessage');
});
it('should log a debug message', () => {
logStub = sandbox.stub(service.logger, 'warn');
service.warn('someMessage');
expect(logStub).to.have.been.calledWith('someMessage');
});
it('should log a debug message', () => {
logStub = sandbox.stub(service.logger, 'error');
service.error('someMessage');
expect(logStub).to.have.been.calledWith('someMessage');
});
});
I am not able to mock winston or fs, so I cannot test the constructor or prevent the creation of the logFolders.
Can anyone help me to mock imports?
Issue Analytics
- State:
- Created 6 years ago
- Comments:15 (5 by maintainers)
Top Results From Across the Web
Isolating Dependencies in Tests Using Mocks and Stubs
Unit tests check on the behavior of units. Think of a class as being a unit. Classes, more often than not, have external...
Read more >Unit Testing Best Practices When You Have External ...
Unit testing with external dependencies may be hard.
Read more >How can I test/mock external code or external dependencies ...
I'm using Moq for mocking of my code in unit testing. It's ok to mock the code without external dependencies. Below code is...
Read more >Mock External Dependencies via Traits - Catch the Dot
In this short blog post, I will give an example wherein we will see how with the help of Scala trait's we can...
Read more >Using Mocks to Test External Dependencies or Reduce ...
So far we've used mocks to test external dependencies, like Django's mail-sending function. The main reason to use a mock was to isolate ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
You are not following IoC You must create injectable component from logger package and inject to constructor.
@mslourens You can create new type by using
typeof
(it behaves differently in TypeScript):or