Testing the receiveMessage function in SQS using Jest unit tests

Struggling to find the right approach for unit testing this function. I almost have it, but can't quite nail it down.

Take a look at the function below:

 receiveMessage(callback: Function): any {
    this.sqs.receiveMessage(
      this.params,
      (err: AWSError, data: ReceiveMessageResult) => callback(err, data)
    );
  }

When it comes to testing, I've set up an initial AWS mock and then customized it in the test:

jest.mock('aws-sdk', () => {
  const SQSMocked = {
    receiveMessage: jest.fn().mockReturnThis()
  };
  return {
    SQS: jest.fn(() => SQSMocked),
    config: {
      update: jest.fn(() => {
        return { region: getConfig().region };
      })
    }
  };
});

const sqs = new AWS.SQS({
  region: 'us-east-1'
});

Next steps involve executing the actual test. I feel like my issue lies in how I'm overriding the receiveMessage on the aws sdk.

  it('verifies that the callback is invoked', (done) => {
    const callback = (err: AWSError, data: ReceiveMessageResult) => {
      console.log('called');
      done();
    };

    // Unsure about how to trigger the callback on the mock???
    sqs.receiveMessage = jest.fn().mockReturnValue(callback);

    sqsQueue.receiveMessage(callback);

    expect(callback).toHaveBeenCalled();
  });

I've attempted various approaches to modifying the aws sdk, sometimes encountering TypeScript errors, but haven't quite cracked how to mock the function callback.

Any suggestions?

Answer №1

After making some changes to the main function, I was able to extract the callback interface:

  receiveMessage(callback: SqsCallback): void {
    this.sqs.receiveMessage(this.params, callback);
  }

The test now simply verifies that the callback is being called:

  it('should call the callback', (done) => {
    const callback: SqsCallback = jest.fn(
      (err: AWSError, data: ReceiveMessageResult) => {
        done();
      }
    );
    const receiveMessageMock = jest.fn((expectedConfig, sqsCallback) => {
      return sqsCallback();
    });
    // @ts-ignore
    sqs.receiveMessage = receiveMessageMock;

    sqsQueue.receiveMessage(callback);
  });

I encountered an issue with TS type checking and had to use ts-ignore for the mock.

Initially confusing, but with a couple of days' effort, I was able to grasp the concept :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a JSX syntax for a simulated component and ensuring it is fully typed with TypeScript

Looking for some innovative ideas on how to approach this challenge. I have a test helper utils with added types: import { jest } from '@jest/globals' import React from 'react' // https://learn.reactnativeschool.com/courses/781007/lect ...

Is it possible to omit certain fields when using the select function in MikroORM?

When working with nested populate queries in MikroORM with MySQL, I am faced with the challenge of selecting 100 fields while wanting to exclude around 20 fields. It would make more sense to leave out those 20 fields, similar to using db.find().select("- ...

Mastering the art of duplicating an array of objects in TypeScript

I attempted the following strategy: this.strategies = []; this.strategiesCopy = [...this.strategies]; Unfortunately, it appears this method is not effective as it results in duplicates. ...

Ways to modify the input field value in my form based on the current page context

I am currently developing a website for a sports event organization company using Angular, HTML/CSS. The focus of this website is on the triathlon sport and it consists of several stages. On the home page, there are five image tags representing each stage ...

Execute a grandchild function in Angular that triggers its grandparent function

I'm currently working with a component structure that looks like this: Component A -> Component B -> Component C Within the template of Component C, there is a button that triggers a function in the 'code behind' when clicked. My go ...

Using Typescript: invoking static functions within a constructor

This is an illustration of my class containing the relevant methods. class Example { constructor(info) { // calling validateInfo(info) } static validateInfo(info):void { // validation of info } I aim to invoke validateInfo ...

Utilize Ant Design TreeSelect to seamlessly integrate API data into its title and value parameters

I am currently working on populating a Tree Select component in ANT Design with data fetched from an API. The response from the API follows this structure: projectData = ProjectData[]; export type ProjectData = { key?: number; projectId: number; ...

Angular rxjs Distinctions

Coming from AngularJS to Angular, I'm still trying to wrap my head around rxjs observable. For example: User.ts export class User { id?:any; username:string; password:string; } Using <User[]> myUser(header: any) { const url = `${this.mainUr ...

Add a feature to a functional component that is enclosed with React.forwardRef

Within my codebase, there exists a component that is wrapped with React.forwardRef and serves as a compound component. One challenge I encountered was how to preserve the functionality of Form.Item = FormItem; while still having the Form component fun ...

Selecting ion-tabs causes the margin-top of scroll-content to be destroyed

Check out the Stackblitz Demo I'm encountering a major issue with the Navigation of Tabs. On my main page (without Tabs), there are simple buttons that pass different navparams to pre-select a specific tab. If you take a look at the demo and click t ...

The method of evaluating in-line is distinct from evaluating outside of the

What causes the compiler to produce different results for these two mapped types? type NonNullableObj1<O> = {[Key in keyof O] : O[Key] extends null ? never : O[Key]} type NotNull<T> = T extends null ? never : T; type NonNullableObj2<T> = ...

What is the reason that the protected keyword is not retained for abstract properties in TypeScript?

I'm uncertain whether this issue in TypeScript is a bug or intended functionality. In my Angular project, I have 3 classes - an abstract service, a service that implements the abstract service, and a component that utilizes the implementing service. ...

Fire the BehaviorSubject with the identical value following a mutation

I am working with a BehaviorSubject where I have to make changes through mutation (for reasons beyond my control). I need to trigger the BehaviorSubject for subscriptions whenever there are changes. Is there another approach I can take instead of using: ...

"Encountered a runtime error while trying to execute the doubleClick() function using Pro

Encountering the following issue: "WebDriverError: Unable to convert: Error 404: Not found" while running a test with protractor: browser.actions().doubleClick(elem).perform(); or browser.actions().click(elem).click(elem).perform(); Uncertain of t ...

What is the correct way to utilize window.scrollY effectively in my code?

Is it possible to have a fixed header that only appears when the user scrolls up, instead of being fixed at the top by default? I've tried using the "fixed" property but it ends up blocking the white stick at the top. Adjusting the z-index doesn&apos ...

Ensuring a User has an Image in MySQL Using Angular 6

As part of my development process, I am working on creating a new user and sending their information along with an image to a MySQL database. The process involves sending a user object with form data through the following component.ts file: subscribeUser() ...

Applying ngClass to a row in an Angular material table

Is there a way I can utilize the select-option in an Angular select element to alter the css-class of a specific row within an Angular Material table? I have successfully implemented my selection functionality, where I am able to mark a planet as "selecte ...

Having trouble importing a tailwind CSS file into a Remix.js project without TypeScript throwing an error

I've attempted to implement the solution found here but unfortunately, it's still not working for me. Below are my configuration files: remix.config.ts: /** @type {import('@remix-run/dev').AppConfig} */ module.exports = { postcss: t ...

TypeScript: Extending a Generic Type with a Class

Although it may seem generic, I am eager to create a class that inherits all props and prototypes from a generic type in this way: class CustomExtend<T> extends T { constructor(data: T) { // finding a workaround to distinguish these two ...

Learn how to extend components in Typescript and determine necessary arguments. Discover how to apply this knowledge in an Angular use case by extending mat-side-nav

Background: The Angular Material Design component known as mat-side-nav operates in a specific structure for its dynamics: <mat-sidenav-container> <mat-sidenav> </mat-sidenav> <mat-sidenav-content> </mat-sidenav-conten ...