Simulating npm package with varied outputs

In my testing process, I am attempting to simulate the behavior of an npm package. Specifically, I want to create a scenario where the package returns a Promise that resolves to true in one test and rejects with an error in another.

To achieve this, I have set up a mock implementation of the npm package at the beginning of my test file, just before the initial test description. The code for mocking the npm package looks like this:

const mockNewFile = (): File => new File(['this is new file content'], 'new-file');
jest.mock('blueimp-load-image', () => () => {
    const newFile = mockNewFile();
    return new Promise(resolve => {
        const data = {
            image: {
                toBlob: (func: (file: File) => File) => {
                    func(newFile);
                }
            }
        };

        resolve(data);
    });
});

By setting up this mock, I can successfully run tests for functions that rely on the blueimp-load-image npm package.

However, I also wanted to include a test case for when the blueimp-load-image function fails to fulfill its promise and returns an error. To do this, I created a new test block within the main test description and attempted to mock the npm package again to return an error:

describe('if loadImage returns an error', () => {
            beforeEach(() => {
                jest.mock('blueimp-load-image', () => () => {
                    return new Promise((resolve, reject) = reject(new Error('something went wrong')));
                });
            });

            test('return the file back unmodified', async () => {
                const expected = {/* file content */};
                const result = await theFunctionUsingLoadImage(file);

                expect(result).toStrictEqual(expected);
            });
        });

The above test does not work as expected, as no error is thrown. This leads me to believe that the mock setup in the beforeEach block is not functioning properly. I have also tried using jest.spyOn instead of Jest.mock, but that approach was unsuccessful.

I am unsure of what I am missing or overlooking in this testing scenario. Can anyone provide guidance?

Answer №1

Jest.mock should be utilized just once and must encompass the entire interface of the mocked library.

There are various options available:

  1. Utilizing mocks, enabling you to create a mock implementation that can provide additional (mock-only) methods.
  2. Using jest.mock with a global variable to determine if the mock should return success or rejection.

This example demonstrates the second option

const mockNewFile = (): File => new File(['this is new file content'], 'new-file');
let shouldSuccess = true;
jest.mock('blueimp-load-image', () => () => {
    const newFile = mockNewFile();
    return new Promise((resolve, reject) => {
        if(!shouldSuccess) {
          return reject('data-of-reject');
        }
        const data = {
            image: {
                toBlob: (func: (file: File) => File) => {
                    func(newFile);
                }
            }
        };

        resolve(data);
    });
});

Simply update the value of shouldSuccess to false in order to make your mock implementation reject.

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

Pop-up message on card selection using JavaScript, CSS, and PHP

I have a total of 6 cards displayed in my HTML. Each card, when clicked, should trigger a modal window to pop up (with additional information corresponding to that specific card). After spending a day searching for a solution online, I've come here s ...

Issue with Remote Form in Rails: Encountering Syntax Error Due to Unexpected Token

I am trying to update a form: <%= form_for([@group, lesson], remote: true) do |f| %> <tr id='<%= lesson.id%>' > <td><%= f.text_field :time %></td> <td><%= f ...

What is the best way to remove extra information from a redirect URL?

Implementing Discord login OAuth2 in JavaScript has been quite a journey. I have managed to redirect to '/auth' upon completion, but the URL for that page comes with additional information like '/auth#token_type=Bearer&access_token=12eka ...

Unable to provide feedback on the input elements

ISSUE: Unable to provide input in the input fields // Enable dragging for the DIV element: dragElement(document.getElementById("mydiv")); function dragElement(elmnt) { var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; if (document.getElementB ...

Switching between height: 0 and height:auto dynamically with the power of JavaScript and VueJS

Currently, I am changing the height of a container from 0px to auto. Since I do not know the exact final height needed for the container, using max-height could be an option but I prefer this method. The transition from 0 to auto works smoothly, however, ...

Integrating CSS with Material-UI in a React project: A step-by-step guide

I am currently developing a project using React (along with TypeScript) and the Material-UI library. One of my requirements is to implement an animated submit button, while replacing the default one provided by the library. After some research, I came acr ...

Trigger the opening of a class or window upon pressing the button

Good evening, I'm attempting to create a functionality where pressing a specific button will open a window. However, I am unsure of how to achieve this using CSS classes. My initial thought was to add a new class in the CSS file and call it every ti ...

What steps can be taken to customize the default keyboard shortcuts functionality in Swiper.js?

I am trying to customize the functionality for left/right keys in Swiper.js but I am unable to find a way to do this through the API () It seems that the API only allows you to disable/enable default actions: mySwiper.keyboard.enabled // Whether th ...

How can I resolve the issue if a specific file within a package cannot be located using NPM?

What are the steps to troubleshoot when a file inside a package cannot be located? Error: Module not found: Can't resolve 'images/loading-icon.gif' ./node_modules/react-pdf-highlighter/node_modules/pdfjs-dist/web/pdf_viewer.css I'm cur ...

Activating Jquery toggle on several elements instead of just the specified element

Hey everyone, I have a question regarding jQuery. I have a toggle function that is supposed to activate when clicking on a specific element - in this case, my logo image with the id of #logobutton. The toggle works great, but there's a problem. The an ...

Is there a way to continuously submit a form in React every 10 seconds, even if it includes events?

I have a form with input fields where I collect data upon form submission. However, I want the form to submit automatically every 10 seconds without the need to click a button or press enter. I tried using useEffect to create an interval, but it resulted i ...

Using Javascript to dynamically add and remove elements on click

Whenever I click on a link, I am able to generate input, label, and text. However, I want to be able to delete these elements with the next click event on the same link: I've tried updating my code like this: var addAnswer = (function() { var la ...

The range slider's color value is not resetting correctly when using the <input>

Before repositioning, the slider is at this location: (both thumb and color are correctly positioned) https://i.stack.imgur.com/J3EGX.png Prior to Reset: Html <input id="xyzslider" class="mdl-slider mdl-js-slider" type="range" min="0.0" max="1.0" va ...

Refresh the data in an existing Highstock chart with JavaScript only

I'm currently updating a website and unfortunately, I do not have access to the original code. All I am able to do is append new code at the end of it. The existing code consists of a highstock chart with specific data attributes. Here is the snippet ...

Tips on integrating JavaScript with embedded Ruby code

I am attempting to generate a flash message that displays after a user clicks a link in my js.erb file. $('a').click(function(){ <% flash.now[:alert]= "Successfully added "%> this.innerHTML <% "to cart" %> }) M ...

Include image hover text without using HTML

I am looking to add a hover effect to some images using CSS and JS since I cannot directly edit the HTML file. The goal is to have centered text pop out when hovering over certain images. I know the div class of the image but unfortunately, I cannot add te ...

Capturing member function details using JSDoc

Here's the code snippet I'm working with: /** This class blah blah... @constructor **/ my.namespace.ClassA = function(type) { /** This function performs an action **/ this.doSomething = function(param){ } } The class will be inc ...

Using JavaScript to open a new window and display CSS while it loads

I am looking to utilize a new window for printing a portion of HTML content. var cssLink = document.getElementByTagName('link')[2]; var prtContent = document.getElementById('print_body'); var WinPrint = window.open(' ...

Turn off the feature that highlights links

Hi there! I'm curious to know if it's feasible to remove the highlighting effect when clicking on a link. I'd like the link to function more like an image, without the appearance of a highlighting box upon clicking. ...

Is there a way to dynamically set the value of a React Material TextField in Auto Select mode?

Here is a React state: const [filterByInvoiceNo, setFilterByInvoiceNo] = useState( 0 ); This represents a React Material TextField: <TextField size="small" type="number" label="Invoice No&quo ...