Tips for testing and verifying the call to a specific Firebase method within a function using Jest

Within the file App.ts, I am utilizing the method

firebase.auth().signInWithEmailAndPassword(email, password)
.

Now, my objective is to conduct a unit test to ensure that when the

myAuthenticationPlugin.authenticate(email, password)
method is invoked from App.spec.ts, it triggers the
firebase.auth().signInWithEmailAndPassword(email, password)
method as this is the core functionality of App.ts.

Despite several attempts, I have been unable to find a solution.

App.ts

const App= {
    authenticate: async (email, password) => {
        await firebase.auth().signInWithEmailAndPassword(email, password)
  },
}

App.spec.ts

import myAuthenticationPlugin from 'authenticationPlugin/App'
import firebase from 'firebase/app'
jest.mock('firebase/app', () => {
  const firebase = {
    auth: jest.fn(() => {
      return {
        currentUser: {
          email: 'test',
          uid: '123',
          emailVerified: true
        },

        signInWithEmailAndPassword: jest.fn().mockImplementation()
      }
    }),
    initializeApp: jest.fn()
  }
  return firebase
})

describe('Test for authenticate ()', () => {
    it('signInWithEmailAndPassword ()', () => {
      const email = 'test'
      const password = 'mypassword'
      myAuthenticationPlugin.authenticate(email, password)
      expect(firebase.auth().signInWithEmailAndPassword).toHaveBeenCalled()
    })
  })

Error Received

● App.js (Authentication Plugin) › Test for authenticate () › signInWithEmailAndPassword ()

    expect(jest.fn()).toHaveBeenCalled()

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

      44 |       const password = 'mypassword'
      45 |       myAuthenticationPlugin.authenticate(email, password)
    > 46 |       expect(firebase.auth().signInWithEmailAndPassword).toHaveBeenCalled()
         |                                                          ^
      47 |     })
      48 |   })
      49 | })

      at Object.<anonymous> (tests/unit/App.spec.ts:46:58)

Answer №1

Below is the solution for the uni test:

app.ts:

import firebase from 'firebase/app';

const App = {
  authenticate: async (email, password) => {
    await firebase.auth().signInWithEmailAndPassword(email, password);
  },
};

export default App;

app.test.ts:

import App from './app';
import firebase from 'firebase/app';

jest.mock('firebase/app', () => {
  return {
    auth: jest.fn().mockReturnThis(),
    signInWithEmailAndPassword: jest.fn(),
  };
});

describe('61352544', () => {
  it('should pass', async () => {
    const email = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d2b7aab3bfa2beb792b5bfb3bbbefcb1bdbf">[email protected]</a>';
    const password = '123';
    await App.authenticate(email, password);
    expect(firebase.auth().signInWithEmailAndPassword).toBeCalledWith(email, password);
  });
});

unit test results with coverage of 100%:

 PASS  stackoverflow/61352544/app.test.ts (12.122s)
  61352544
    ✓ should pass (9ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 app.ts   |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.061s

source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61352544

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 Vue-cli webpack development server refuses to overlook certain selected files

I am attempting to exclude all *.html files so that the webpack devserver does not reload when those files change. Here is what my configuration looks like: const path = require('path'); module.exports = { pages: { index: ...

The object does not have a property named 'fetch' and therefore cannot be read

Struggling to integrate a REST datasource into my Apollo Server. I've created a class that extends RESTDataSource for handling API requests. However, when attempting to call the login method from my GraphQL resolver code, an error is being thrown. An ...

Using React's `cloneElement` to make modifications to a child component while maintaining the reference within a functional component

In the past, I had references in my component while rendering, and it was functioning as expected: // props.children is ReactElement<HTMLDivElement>[] const [childRefs] = useState<RefObject<any>[]>(props.children.map(() => createRef()) ...

Ways to retrieve information from a promise that has been rejected

Can someone provide me with detailed information on why a request failed, such as an existing username or email already in use? The console only displays a generic "Bad Request" error without specifics. I noticed that I can return a promise containing data ...

Is there a way to improve the efficiency of this jQuery function that toggles the image source?

I have implemented a functionality that seems to work, but I'm unsure if it's the most efficient solution. I couldn't find a ready-made 'copy-paste' solution online, so I ended up writing this code myself. I am sticking with the &l ...

What is the best way to configure dependencies for a production deployment when utilizing Babel within the build script?

From what I understand, Babel is typically used for compiling code, which is why it usually resides in devDependencies. However, if I incorporate the Babel command into my build script and want to run npm install --only=prod before running npm run build d ...

Allow users to interact with table rows by making them clickable and sending a post parameter to a jQuery

After creating a table and populating it with elements using JSTL tags and EL expressions, the next step is to make each row clickable. This can be achieved by implementing the following function: $("tr").click(function() { window.location.href = $(th ...

A guide on selectively removing a value from a javascript object when calling setState in ReactJS

updateDishDetails(id, quantity) { if (quantity !== 0) { this.setState( prevState => ({ bookingFormData: { ...prevState.bookingFormData, dishDetails: { ...prevState.bookingFormData.dishDe ...

The call stack size has reached its maximum limit;

Encountering an issue with the use of componentDidMount(). This method is intended to display a Tooltip by utilizing the function _getContentTooltip(). However, the problem arises as it triggers the error message common.js:444 RangeError: Maximum call st ...

"Combining JSON, JavaScript, and HTML for dynamic web development

I am a junior computer programmer facing challenges with our JSON project. The objective is to store an object in local storage, but my HTML and JS code are not working as intended. It seems like nothing happens at all. Any suggestions or feedback would ...

What is the best way to showcase information within a node framework?

I am looking to create a family tree using the MVC framework. Furthermore, I need to be able to insert data with relationships. I have object data that I would like to display along with its entities in a node structure. Any assistance on this matter wou ...

Angular UI grid: Arranging numbers in a straight line at the decimal point

I am interested in aligning decimal numbers in Angular UI Grid as shown below. 11.293 .89 233424 .34345 I have considered different approaches such as using a cell template with aligned divs or transparent 0s. Has anyone successfully imp ...

Exploring AngularJS Service: simulating $rootElement and $rootScope for testing purposes

Currently, I am in the process of writing tests for a service responsible for updating meta information on a page. mod.service('MetaSrv', ['$rootScope', '$rootElement', function ($rootScope, $rootElement){ return { updat ...

Can functions be used as keys in a collection in JavaScript's map?

Using functions as keys in JavaScript can be tricky because for js objects, functions are converted to their "toString" form. This poses a problem if two functions have the same body. var a = function() {}; var b = function() {}; var obj={}; obj[a] = 1; o ...

Passing arguments to the callback function in React: a comprehensive guide

Within my react component, I have a collection of elements that I want to make clickable. When clicked, I trigger an external function and pass the item ID as an argument: render () { return ( <ul> {this.props.items.map(item => ( ...

Error encountered during Typescript compilation: Type 'void' cannot be assigned to type 'Item[]'

Below are my typescript functions. When I edit in vscode, the second function does not show any error message. However, upon compilation, an error is displayed for the second function: error TS2322: Type 'Promise<void>' is not assignable t ...

Upon submission, the form is processed and 'false' is returned

Does anyone know how I can use ajax to save form data? I am encountering an issue where the page refreshes when all entries are correct. If I input any incorrect data and submit, it displays an error. However, if I then fill in all correct information, it ...

Leveraging a VueJS prop as a variable in an array mapping operation

Trying to figure out a solution where a variable (prop) can be used in an array map function. The initial code snippet looks like this: var result = this.$store.getters['example/store'].map(a => a.fixed_column) I aim for fixed_column to be ...

Learn how to utilize ng2-file-upload in Angular for uploading .ply files effortlessly!

I'm currently working on uploading various files using ng2-file-upload. I've been successful in uploading different file types like png and jpg, but I'm facing an issue with the .ply file extension. Can someone guide me on how to upload a fi ...

Having trouble getting jQuery autocomplete to recognize the JavaScript data file

Struggling to use a JQuery UI widget to call in a JS file containing string data. I keep getting 'no results found' with no console errors. It seems like I'm not referencing the file correctly, as my knowledge of jquery/js is limited. Any gu ...