Following the guidelines outlined in the ES6 Class Mocks page of the Jest documentation, I attempted to test a method on a TypeScript class called Consumer
. The Consumer
class instantiates a Provider
object and invokes methods on it, prompting me to mock the Provider
class.
Here is the directory structure for reference:
.
├── __tests__
│ └── consumers
│ └── Consumer.test.ts
└── js
├── providers
│ └── provider.ts
└── consumers
└── Consumer.ts
The content of provider.ts
:
export class Provider {
constructor() {}
public action(params) {
// perform necessary tasks that need mocking
return something;
}
}
The code from Consumer.ts
:
import {Provider} from "../providers/provider";
export class Consumer {
private provider: Provider;
constructor() {
this.provider = new Provider();
}
public doSomething() {
const result = this.provider.action(params);
// process 'result'
}
}
In my initial attempt, I used a default "automatic mock":
Consumer.test.ts
:
import {Consumer} from "../../js/consumers/Consumer";
jest.mock("../../js/providers/provider");
test("Consumer doSomething", () => {
const consumer = new Consumer();
consumer.doSomething();
});
Although successful in using a mock implementation, I needed to ensure that Provider.action()
returned a value. Thus, I proceeded with:
// initially ensuring basic functionality before customization
const mockAction = jest.fn();
jest.mock("../../js/providers/provider", () => {
return jest.fn().mockImplementation(() => {
return {action: mockAction};
});
});
test("Consumer doSomething", () => {
const consumer = new Consumer();
consumer.doSomething();
});
Despite various attempts to alter the mock, I have been unable to find a solution that allows me to use Consumer
as intended in my tests. My preference is to avoid manual mocks to maintain a cleaner codebase and facilitate diverse mock implementations for different tests.