Sure, here's an example of mocking an asynchronous function with Mocha in TypeScript:
typescript
// myModule.ts
export class MyClass {
async fetchData(): Promise<string> {
return await this.makeApiCall();
}
private async makeApiCall(): Promise<string> {
// Asynchronous API call implementation
return 'data from API';
}
}
// myModule.test.ts
import { MyClass } from './myModule';
import * as sinon from 'sinon';
import { expect } from 'chai';
describe('MyClass', () => {
let myClassInstance: MyClass;
let sandbox: sinon.SinonSandbox;
beforeEach(() => {
sandbox = sinon.createSandbox();
myClassInstance = new MyClass();
});
afterEach(() => {
sandbox.restore();
});
it('should fetch data successfully', async () => {
// Mock the private makeApiCall method
const mockedMakeApiCall = sandbox.stub(myClassInstance, 'makeApiCall').resolves('mocked data');
const result = await myClassInstance.fetchData();
expect(result).to.equal('mocked data');
expect(mockedMakeApiCall).to.have.been.called;
});
it('should handle error in fetchData', async () => {
// Mock the private makeApiCall method to reject with an error
const mockedMakeApiCall = sandbox.stub(myClassInstance, 'makeApiCall').rejects(new Error('API error'));
try {
await myClassInstance.fetchData();
} catch (error) {
expect(error.message).to.equal('API error');
expect(mockedMakeApiCall).to.have.been.called;
}
});
});
In this example, we have a `MyClass` that has an asynchronous `fetchData` method, which in turn calls a private `makeApiCall` method.
In the test suite, we use the following techniques to mock the asynchronous behavior:
1. Create a Sinon sandbox: We use `sinon.createSandbox()` to create a sandbox for managing the mocks.
2. Mock the private method: We use `sandbox.stub()` to create a stub for the `makeApiCall` method and replace its implementation with a mocked version.
3. Mock successful response: In the first test, we use the `resolves()` method to set the resolved value of the mocked `makeApiCall` method to `'mocked data'`.
4. Mock error response: In the second test, we use the `rejects()` method to set the rejected value of the mocked `makeApiCall` method to a new `Error` instance with the message `'API error'`.
In the tests, we then call the `fetchData` method and assert the expected behavior:
- In the first test, we expect the `fetchData` method to return the mocked data and verify that the `makeApiCall` method was called.
- In the second test, we expect the `fetchData` method to throw the mocked error and verify that the `makeApiCall` method was called.
Finally, we use the `afterEach` hook to restore the sandbox after each test to ensure a clean state for the next test.
By using these techniques, you can effectively mock asynchronous functions in TypeScript when using Mocha as your testing framework.