There are several ways to do this.
The easiest way without additional libraries
Save the service as a property of the class and call it from there:
import Service from 'service'; const service = Service(...); class MyLib { constructor() { this.service = service; } ... now you should call service in a bit different way ... this.service.put(foo) ... ... this.service.get(bar) ... } export default MyLib;
Then you can rewrite the service instance in your tests:
it('should call my mock', () => { const lib = new MyLib(); lib.service = mockedService; // you need to setup this mock, with Sinon, for example lib.doSomething(); assert.ok(mockedService.put.calledOnce); // works });
Mock require () function
There are several libraries that allow you to override the results of the require() function. My favorite proxyquire . You can use it and your module will get mockedSerice instead of the real one:
import proxyquire from 'proxyquire'; it('should call my mock', () => { const MyLib = proxyquire('./my-lib', { // pass here the map of mocked imports service: mockedService }) const lib = new MyLib(); lib.doSomething(); assert.ok(mockedService.put.calledOnce); // works });
Use rewire to access module closure
Rewire is a special library that encodes the module code, so you can change any local variable there
import rewire from 'rewire'; it('should call my mock', () => { const MyLib = rewire('./my-lib') const lib = new MyLib(); // __set__ is a special secret method added by rewire MyLib.__set__('service', mockedService); lib.doSomething(); assert.ok(mockedService.put.calledOnce); // works });
In addition, there is babel-plugin-rewire for better integration with your tools.
All of the above methods are good, you can choose what is best for your problem.
source share