What is the best way to mimic a library using SinonJs?

I am dealing with a file named browser-launcher.ts

import * as Browser from "@lib/browser";
    
class BrowserLauncher {
    launch(options) {
       browser = Browser(options);
    }
}
    
export const browserLauncher = new BrowserLauncher()

What is the best way to mock the library '@lib/browser' in order to test the launch method of BrowserLauncher?

How can I properly test the variable browserLauncher in the module browser-launcher.ts?

Answer №1

Sinon is not designed to handle the specific issue of substituting a module for a fake one at the module loader level. This task is typically addressed by third-party libraries like proxyquire and rewire. These libraries specialize in module substitution, commonly referred to as a "link seam" in testing literature.

For CommonJS environments, the Sinon team has provided a helpful guide on how to address this issue. You can find more information at https://sinonjs.org/how-to/link-seams-commonjs/.

If you are encountering the @lib/... string, it may indicate a webpack-specific problem. In such cases, it is recommended to explore module replacement libraries tailored for webpack, such as inject-loader.

Although Sinon can sometimes be used to replace exports within a module, this is highly dependent on the environment. ES Modules, for example, export an immutable namespace, making it challenging to override exports in a standard manner.

If you wish to stub exports, you may need to deviate from ES Module standards by producing writable exports or adjusting the read-only nature of your environment.

Alternative Testing Approaches

In a separate answer, I discuss two methods of employing plain dependency injection to address this issue without external tools. While straightforward, these approaches may require minor changes to your production code for testing purposes. It's important to weigh the pros and cons of introducing code changes versus additional dependencies.

For a more detailed example of this technique, you can refer to a discussion on the Sinon issue tracker where I demonstrate how to optionally inject dependencies: a more elaborate example of this technique on the Sinon issue.

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

In ES6, instantiate a fresh new instance of this

Can a new instance of self/this be generated using ES6 inside a static method? For instance; class myClass { static model() { return new this; } } Is there a standard approach for this situation? Thank you very much. ...

Notification continuously appears when clicking outside of Chrome

I have implemented the use of onblur on a text box to display an alert. However, I encountered an issue where if I click outside my Chrome browser after entering text in the text box and then click on the Chrome browser button in the task bar, the alert ap ...

What is the best approach for incorporating sub-navigation within a page popup in a Next.js project?

In the midst of my Next.js project, there is a requirement to showcase a chat popup consisting of multiple sub-pages like user registration, conversation page, and more. Hence, seamless navigation inside this popup is necessary. The idea is not to alter th ...

What is preventing JSFiddle from displaying this object?

I'm currently experimenting with objects in Angular. While using JSFiddle to define some JSON objects in an Angular controller, I've encountered a problem - it's not working and I can't seem to figure out why. Can someone with fresh ey ...

Assess html code for Strings that include <% %> tags along with embedded scripts

Having a small issue with my code where I am receiving an HTML response from a web service as a java String. I need to display this String as HTML on my webpage, but the problem is that there are some script tags in the form of <% ... %> which are sh ...

Removing an embedded document from an array in MongoDB using Mongoose when the document's status is set to false

I am in desperate need of a solution for this mongoose-related issue. My tech stack includes Express, Mongoose, and GraphQL. To give you some context, I have two collections: users and groups. user { name: string, groupAsMember: [groups], status: bo ...

Tips for capturing and storing video with HTML5 WebRTC

Before reading the description, make sure to run the code snippet first. This will provide you with a better understanding of the structure. In the 2nd video element, I am trying to record, play, and save video. The issue I'm encountering is that the ...

Express.JS failing to save data to file when using NeDB

Currently, I am developing a bulk import feature for my personal password manager and I have encountered a problem. The issue arises when trying to import an array of passwords using the forEach() method to iterate through each one. After calling the inse ...

Using Angular's filter pipe to search within a nested array

We are attempting to implement an angular pipe for filtering a list of sub-items, with the goal of removing parent items if there are no child items present. Here is the HTML code snippet we are using: <div class="row border-bottom item" *n ...

Using parameters to create unions in TypeScript

Is there a standard method to parametrically define a union? I'm searching for a way to generically define something like: type U<K> = T<K1> | T<K2> | ... | T<Kn> // Where K === (K1 | ... | Kn) Note: I'm encountering a s ...

Is it possible to incorporate a Node.js library into an HTML document?

I am working on an HTML file where I want to incorporate the nodemailer library to handle email sending. Although in nodejs, I can easily include var nodemailer = require('nodemailer') at the beginning of the script section of my HTML file, it ap ...

Node.js server crashes upon automatic startup but remains stable when started manually

Currently, I am using Node.js and Socket.io to power an online chat feature. To manage the server, I have created a configuration file located at: /etc/init/example.conf The contents of this file are as follows: start on startup exec forever start /var/ ...

The issue arises when a continuous use of angularjs directives linked with an external template fails to display correctly upon the addition of new

In the code snippet below, you'll find a fiddle that displays 3 columns of numbers that increase in value. These columns represent directives with different templates: one inline, one preloaded, and one from an external template. When you click on the ...

Obtain the URL for the JavaScript code that is currently running

Can anyone help me find the URL of the JavaScript currently being executed? I am aware of using window.location.href for the current page, but that doesn't necessarily provide the path to the script that is running. Any assistance would be greatly ap ...

The feature of "compile on save" is not functioning properly in my current Angular project

Yesterday I used the angular cli (ng new my-app) to create a new project, but unfortunately the "compile on save" option is not functioning properly. Interestingly, I have two projects on my computer and this feature works fine for one of them but not for ...

Background image that is vertically responsive

I'm struggling with getting a full-page background image to maintain a consistent margin around all sides, especially at the bottom. I want the image to be vertically responsive using only CSS, without relying on Javascript. Any suggestions on how to ...

What is the best way to send a form using ajax?

I am having trouble submitting forms without a post back using AJAX. My code is not working as expected. What could be the issue in my script? I am new to AJAX and would appreciate some help with AJAX scripts. Below you can find my code: Please note: I ...

Issues with routing on Zeit Now platform are causing a 404 NOT FOUND error when attempting to reload pages that are not the

Recently, I purchased a Next.js template from Themeforest and attempted to deploy it to Zeit Now. This particular project is set up as a monorepo using Lerna and Yarn workspace. The code for the Next.js app can be found inside the packages/landing folder. ...

Upon sending an HTTP POST request from JavaScript to a Node server, the body was found to be

Trying to make an XMLHttpRequest from JavaScript to my node server. This is the request I am sending: var data = { "fname": "Fasal", "lname": "Rahman" }; var body = JSON.stringify(data); var xhttp = new XMLHttpRequest(); xhttp.open("POST", "/admin"); xhtt ...

JavaScript's Date() function accurately displays the timezone, but it inconsistently displays the

I have encountered an unusual behavior while attempting to retrieve the current date using Date() in JavaScript. Initially, I changed the timezone to Cuba with the command: sudo ln -sf /usr/share/zoneinfo/Cuba /etc/localtime Subsequently, I executed Date ...