Anticipated the invocation of spyOn function should occur in Jest

Having trouble testing my methods and getting stuck with my if statement not being called. I'm new to Jest, so I have a feeling it's just a simple mistake on my end.

 describe('isSingleScreen', () => {
    beforeEach(() => {
      jest.clearAllMocks();
      jest.spyOn(utilMethods, 'isDualScreen').mockReturnValue(true);
    });

    it('autoScreenAdd', () => {
      // Arrange
      const singleScreenAddSpy = jest.spyOn(
        singleScreenMethods,
        'singleScreenAdd'
      );
      const dualScreenAddSpy = jest.spyOn(dualScreenMethods, 'dualScreenAdd');

      // Act
      utilMethods.autoScreenAdd({});

      // Assert
      expect(singleScreenAddSpy).toBeCalledTimes(0);
      expect(dualScreenAddSpy).toBeCalled();
      expect(dualScreenAddSpy).toBeCalledTimes(1);
    });
  });

export const isDualScreen = (): boolean => {
  return Dimensions.get('window').width > 1000 ? true : false;
};

export const autoScreenAdd = (element: IDualComponent) => {
  if (isDualScreen()) {
    dualScreenAdd(element);
  } else {
    singleScreenAdd(element);
  }
};

Encountering the following error:

    expect(jest.fn()).toBeCalledTimes(expected)

    Expected number of calls: 0
    Received number of calls: 1

      30 |       // Assert
      31 |       expect(autoScreenAddSpy).toBeCalled();
    > 32 |       expect(singleScreenAddSpy).toBeCalledTimes(0);
         |                                  ^
      33 |       expect(dualScreenAddSpy).toBeCalled();
      34 |       expect(dualScreenAddSpy).toBeCalledTimes(1);
      35 |     });

Answer №1

When testing a module that contains functions calling other functions within the same module, there are limitations to consider. For further insight on this topic, you can refer to this informative article. The article discusses various workarounds that may be suitable for your code structure.

Example in Action:

View CodeSandbox Example

Utility Functions

We have slightly modified the original utility functions. If needed, you can adapt your utility modules accordingly based on this example.

const isDualScreen = () => {
  return window.width > 1000 ? true : false;
};

const autoScreenAdd = element => {
  if (utilMethods.isDualScreen()) {
    utilMethods.dualScreenAdd(element);
  } else {
    utilMethods.singleScreenAdd(element);
  }
};

const dualScreenAdd = element => {
  return element;
};

const singleScreenAdd = element => {
  return element;
};

// Ensure proper function mocking in tests by following this structure.
// Repeat this pattern for modules like singleScreenMethods and dualScreenMethods
const utilMethods = {
  singleScreenAdd,
  dualScreenAdd,
  autoScreenAdd,
  isDualScreen
};

export default utilMethods;

Testing Scenario

import utilMethods from "./utils";

describe("isSingleScreen", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    jest.spyOn(utilMethods, "isDualScreen").mockReturnValue(true);
  });

  it("autoScreenAdd", () => {
    // Arrange
    const singleScreenAddSpy = jest.spyOn(utilMethods, "singleScreenAdd");
    const dualScreenAddSpy = jest.spyOn(utilMethods, "dualScreenAdd");

    // Act
    utilMethods.autoScreenAdd({});

    // Assert
    expect(singleScreenAddSpy).toHaveBeenCalledTimes(0);
    expect(dualScreenAddSpy).toHaveBeenCalledTimes(1);
  });
});

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

The Cordova InAppBrowser plugin has not been properly set up

After running cordova plugin list, I noticed that the InAppBrowser plugin is listed. However, when I try to run my code on an android device, I receive this message in the console via Chrome Remote Debugger: Native: InAppBrowser is not installed or you ar ...

Delivering compressed files in a React server

Having some trouble serving a gzip compression of my bundle.js file in React. Have tried reducing the size with uglify and dedupe, but only saw a small decrease from 2.9mb to 2.6mb. Using the compression plugin now outputs a gzip file, however, still servi ...

Steps to trigger a dialog to appear automatically within an Icon Menu with React Material UI

In my application, I have an icon menu implemented along with an array that contains the possible values for the items in the menu. Here is an example of how the array looks: listItems = { [ { label: 'ZERO', t ...

Adjust property value based on changes in a related property

Currently, I am developing a TypeScript-powered Angular (5) application and I have encountered a puzzling question that is proving elusive to solve. Let me illustrate with the following example: ... export class SomeComponent implements onInit { ... ...

React component is failing to re-render after updating state

After spending two days troubleshooting an issue in my project, I am reaching out here for help. The problem arises while rendering an array by calling a child component within the parent component like this:- Parent component {this.state.list.map((it ...

In the production and development environments, the interpretation of CSS classnames is being rearranged

Currently utilizing create-react-app v2. I've encountered an issue with a component that has multiple classnames: "x15 x14 login-form__field". Strangely, in the production build, the order of '.x14' and 'login-form__field' seems t ...

Utilizing *ngFor to display elements with odd indices

Within my Angular application, I have successfully used a loop to populate the 4 employeeList components. Here is the code snippet: <div *ngFor="let record of records"> <p-panel> <div comp-employeeList [listFilter]="record.Filte ...

Encountering an issue such as "Exceeding the maximum number of re-renders. React restricts the amount of renders to avoid

Currently, I am attempting to update the state within the request data method for a string variable as shown below: const ViewChangeRequest = () => { const [requestStageValue, setRequestStage] = useState(''); const { data: request ...

The Angular TypeScript lexicon scope becomes obscured when nested within a third-party API event handler function

I'm having trouble managing scope context in an Angular component while working with a third-party API (ESRI ArcGIS JavaScript API 4.7). I am specifically struggling when trying to handle an event from the ArcGIS API using their event handler callback ...

Material UI transitions between states when an individual item from the ItemList is clicked

Currently facing an issue with selected props from material UI. My goal is to have only one item selected at a time when clicked, but right now both items get selected simultaneously when any one of them is clicked. I hope that explanation is clear. impo ...

Is it possible to include pseudo element elements in the configuration of a custom theme in Material UI?

Within my file themeConfig.js, I have defined several theme variables that are utilized to style different components throughout my application. Among these variables, there is a need for implementing the -webkit scrollbar styles for certain components. Du ...

React : Installation from NPM is unsuccessful

After attempting to install a package in my react app using npm, I encountered an issue where it failed and displayed the error message: npm ERR! Object for dependency "@babel/generator" is empty. npm ERR! Something went wrong. Regenerate the pa ...

Implement the useEffect() function to handle the loading of external JavaScript on the client-side, replicating the

I have encountered a challenge while trying to integrate a rich text editor into my NextJS project. Since there are no available React components for this specific editor and it operates solely on the client side, I am required to load the necessary JavaSc ...

Deactivating toolbar in material table in ReactJS while maintaining default functionalities

https://i.sstatic.net/XrA3I.pngHow can I remove the toolbar to eliminate the blank space between the table and button without disabling the add new row functionality? <MaterialTable title=" " options={{ ...

Deriving union type in Typescript from values within a module or object

I'm trying to find a method similar to keyof typeof myModule in typescript. However, instead of a union of key strings, I need a union of the value types. I have a module with an increasing number of exports - myModule.ts: export const Thing1; expor ...

The attribute 'attribs' is not found on the 'Element' type in cheerio

When I run my code, I encounter an error that says Property 'attribs' does not exist on type 'Element'. It's puzzling to me why this error is being thrown. After examining the type definitions of cheerio, I discovered that attribs ...

Encountering an issue upon launching a new next.js project

Upon setting up my next.js project and running it, I encountered the following error: Error - ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[2].oneOf[8].use[1]!./node_modules/next/dist/build/webpack/loaders/postc ...

What is the best method for storing dynamic values and attribute labels in a state within a React.js application?

I am currently working with react js. On my single product page, I have an array of objects called attributes that I need to display in the user interface. Here is a preview of how it looks: https://i.sstatic.net/GttrD.png My goal is to retrieve and stor ...

Triggering multiple functions by clicking on the Icon

I'm trying to execute two different functions when the user clicks on the Icon, but I keep getting an error that says: Expected onClick listener to be a function, instead got a value of object type. Can someone please help me figure out what I am doin ...

The rule 'import/no-cycle' definition could not be located

After removing my npm package along with the package.lock.json file, I proceeded to run 'npm install' and followed up with 'npm update'. However, upon starting my application using 'npm run start', an error occurred. Upon lau ...