2

I have a HTML select with some options which when I press a button get submitted to a server. Depending on the response an alert is shown. The method looks like this:

 const sendOrder = async (json : string) => {
        const request = await fetchUrl("<irrelevant url>", "POST", json);
        if(request.status === 200){
            const order = await request.json();
            alert(`Created Order #${order.data.id}`)
        }else{
            alert("Order failed")      
        }
    } 

Now I have mocked the server using msw and my test looks something like this:

it('should create an order', async () => {

        render(<ArticleList />);
        render(<ShoppingCart afterSubmit={()=> {}}/>)

        const articlesList = getNullSafeElement('articles');
        await waitFor(() => {
            expect(articlesList.children.length).toBe(2);
        })
        const orderButton = getNullSafeElement('submitBtn');
        const shoppingCart =  document.querySelector('#cart') as HTMLSelectElement; 
        const addressInput = document.querySelector('#address') as HTMLInputElement;

        addressInput.value = "testAddress"
        expect(shoppingCart.options.length).toBe(0);
        fireEvent.click(articlesList.children[0]);
        expect(shoppingCart.children.length).toBe(1);
        fireEvent.click(orderButton);
        
      });

I know for sure that this test runs as expected and that the request is definetly beeing sent to the mocked server by fireEvent.click(orderButton). However, if I now want to do something like this expect(global.alert).toHaveBeenCalledTimes(1), it does not work. Now I know that I have to mock the call and I saw some posts on SO about this issue

Mock or asser whether window.alert has fired

Test alert in React Native

But neither global.alert = jest.fn(), nor jest.spyOn(global, 'alert') have worked out. Both result in 0 calls.

So my question is: How can I test if alert() has been called in my test?

(I am creating a frontend using create-react-app with the typescript template and testing with Jest)

L.Gashi
  • 183
  • 1
  • 11
  • Did you use `waitFor` when checking if it was called? – WebbH Jul 01 '21 at 22:10
  • I tried it with `waitFor` and without, in both cases the test fails telling me : `expect(jest.fn()).toHaveBeenCallesTimes(expected) Expected number of calls: 1 Received number of calls: 0` – L.Gashi Jul 01 '21 at 23:22

1 Answers1

0

Might be a late but I ran into same problem.

I resolved it by using await ahead of the fireEvent click. In your case,

it('should create an order', async () => {
    global.alert = jest.fn();

    render(<ArticleList />);
    render(<ShoppingCart afterSubmit={()=> {}}/>)

    const articlesList = getNullSafeElement('articles');
    await waitFor(() => {
        expect(articlesList.children.length).toBe(2);
    })
    const orderButton = getNullSafeElement('submitBtn');
    const shoppingCart =  document.querySelector('#cart') as HTMLSelectElement; 
    const addressInput = document.querySelector('#address') as HTMLInputElement;

    addressInput.value = "testAddress"
    expect(shoppingCart.options.length).toBe(0);
    fireEvent.click(articlesList.children[0]);
    expect(shoppingCart.children.length).toBe(1);
    await fireEvent.click(orderButton);
    expect(global.alert).toHaveBeenCalledTimes(1);
  });
Shaurcasm
  • 33
  • 6