Ожидаемая фиктивная функция была вызвана один раз, но она была вызвана ноль раз - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть этот тест в jest-js, который должен издеваться над извлечением продукта из бэкэнда, а затем изменять DOM, как показано ниже:

describe("View a single product information", () => {
    let fetchMock;
    beforeEach(() => {
        document.body.innerHTML += `
      <div id ='notify'></div>
      <div id="product"></div>
      <form id="searchbox">
      <input type="search" id="searchbox" value =4 onsearch="getProductByID()">
      </form>
    `;
        fetchMock = jest.spyOn(global, 'fetch');
        fetchMock.mockImplementation(() => Promise.resolve({
            json: () => ({Message:"Product retrieved successfully!"})
        }));
        require('../UI/js/singleProd');
    });

    afterEach(() => {
        fetchMock.mockRestore();
    });

    it('should fetch a product, change content of #product', async () => {
       // window.history.pushState({}, 'searchbox', 'https://store-manager-api-app-v2.herokuapp.com/api/v2/products/4');
        const val= document.getElementById('searchbox').submit();
        const token = localStorage.getItem("token");
        expect(fetchMock).toHaveBeenCalledTimes(1);
        const fetchArgs = fetchMock.mock.calls[0];
        expect(fetchArgs[0]).toBe(`https://store-manager-api-app-v2.herokuapp.com/api/v2/products/${val}`);
        expect(fetchArgs[1]).toEqual({
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin':'*',
                'Access-Control-Request-Method': '*',
                'Authorization': `Bearer ${token}`
            },
            method: "GET",
            mode: "cors",
        });
        // pause synchronous execution of the test for two event loop cycles
        // so the callbacks queued by the then()'s within signUp have a chance to run
        await Promise.resolve().then();
        await Promise.resolve().then();
        expect(document.getElementById('product').innerHTML).not.toBeNull();
        expect(document.getElementById('notify').innerHTML).toBe(`<div class="isa_success">
    <i class="fa fa-check"></i>
    Product retrieved successfully!
</div>`)
    });
});

Файл, который я пытаюсь проверить, приведен ниже.Я в основном слушаю окно поиска, а затем получаю введенное значение, чтобы использовать его для поиска продукта в моем бэкэнде.

const searchbox = document.getElementById('searchbox');
if(searchbox){
    searchbox.addEventListener('search', getProductByID)
}
function getProductByID(){

    const token = localStorage.getItem('token');
    const access_token = "Bearer " + token;
    if (token === null){
        let notify = document.getElementById("notify");
        notify.innerHTML =`<div class="isa_error">
   <i class="fa fa-times-circle"></i>
   Please login to view the products page!
</div>`
    }
    fetch(`https://store-manager-api-app-v2.herokuapp.com/api/v2/products/${searchbox.value}`,{
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin':'*',
            'Access-Control-Request-Method': '*',
            'Authorization': access_token
        },
        method:"GET",
        mode: "cors",
    })
        .then(function(response)
        {
            return response.json()

        })
        .then((data) => {
            console.log(data.Message);
            let output = '<div></div>';
            output+=`
    <div class="prod-profile">
    <img src="../images/mystoresbg.jpg" alt="Store logo" style="width:100%">
    <h1>${data["Product Profile"].prod_name}</h1><hr>
    <p id="prod_id"> Product ID: ${data["Product Profile"].prod_id}</p> <hr>
    <p class="price">Price: ${data["Product Profile"].prod_price}</p><hr>
    <p class="description">Description: ${data["Product Profile"].prod_description.substring(0,30)}</p>
    <hr>
    <p class="quantity">Quantity: ${data["Product Profile"].prod_quantity}</p>
    <hr>
    <p>Minimum Allowed Qty: ${data["Product Profile"].minimum_allowed}</p>
    <hr>
    <p>Category: ${data["Product Profile"].prod_category}</p>
    <hr>
    <button id="btndelete" onclick="deleteProductByID();">Delete Product</button>
    </div>
    `
            ;
            let notify = document.getElementById("notify");
            notify.innerHTML =
                `<div class="isa_success">
    <i class="fa fa-check"></i>
    Product retrieved successfully!
</div>`;
            product_id = data["Product Profile"].prod_id;
            localStorage.setItem('product_id', product_id);
            document.getElementById('product').innerHTML = output;
        })

}

Я получаю эту ошибку при запуске теста:

Error: expect(jest.fn()).toHaveBeenCalledTimes(1)

Expected mock function to have been called one time, but it was called zero times.

      63 |         const val= document.getElementById('searchbox').value;
      64 |         const token = localStorage.getItem("token");
    > 65 |         expect(fetchMock).toHaveBeenCalledTimes(1);
         |                           ^
      66 |         const fetchArgs = fetchMock.mock.calls[0];
      67 |         expect(fetchArgs[0]).toBe(`https://store-manager-api-app-v2.herokuapp.com/api/v2/products/${val}`);
      68 |         expect(fetchArgs[1]).toEqual({

      at toHaveBeenCalledTimes (__tests__/singleProduct.test.js:65:27)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (__tests__/singleProduct.test.js:3:191)
      at __tests__/singleProduct.test.js:3:437
      at Object.<anonymous> (__tests__/singleProduct.test.js:3:99)
...