Reputation: 247
I want to mock a global variable and test if it has been called in my function. In my file, I define a global variable "remote" which instanciates a Subject (RxJS library). I just want to test if the next function of Subject has been called with the right parameter "name". However, I can't access the global variable remote in my test file. I tried to mock it in my setup file, but doesn't work.
How can I do that ?
const remote = new Subject();
const analytics = {
click: (name) => {
if (name) {
remote.next(name);
}
}
}
module.exports = analytics;
Thanks !
Upvotes: 1
Views: 2607
Reputation: 5530
This is a good question. When you use webpack, your individual file is wrapped into different function call. Check out this doc.
The best part of this question is that it shows the necessity of IOC/DI if you want your code to be testable. Instead of defining remote
in your local module, you can export an Analytics
class and then inject remote
to its constructor.
// Analytics.js
export default class Analytics{
constructor(remote) {
this.remote = remote
}
click(name) {
if (name) {
this.remote.next(name)
}
}
}
main.js
import Analytics from './Analytics'
const remote = new Subject()
const analytics = new Analytics(remote)
analysis.click('foo')
It would be tedious to inject dependencies to all components/services. Angular has an decent doc on why/how to simplify it. Hope this is helpful!
// Update
You can use window to define global constant and access it in tests by using window.remote
const remote = new Subject()
window.remote = remote
When you want to mock remote, remember to modify its properties rather than the reference to it.
// test.js
beforeEach(() => {
// wrong !!!
window.remote = {
next(name) { assert(name) }
}
// right
window.remote.next = name => assert(name)
})
Upvotes: 1