I am trying to prove that the price is being set on the component.
I have the following HTML:
<template>
<h1>Current price of a bitcoin in Euro</h1>
<lightning-formatted-number
currency-code="EUR"
format-style="currency"
value={euroPrice}>
</lightning-formatted-number>
</template>
And the following JavaScript:
import {LightningElement, api, track} from 'lwc';
const bitcoinPriceProvider = 'https://api.coinbase.com/v2/prices/spot?currency=EUR';
export default class BitcoinEuroPrice extends LightningElement {
@api
refreshRateInSeconds;
@track
euroPrice;
connectedCallback() {
this.fetchPrice();
setInterval(this.fetchPrice, this.refreshRateInSeconds * 1000);
}
fetchPrice() {
fetch(bitcoinPriceProvider)
.then(response => response.json())
.then(json => {
this.euroPrice = json.data.amount;
console.log('######## this.euroPrice: ', this.euroPrice);
});
}
}
This is my test:
import {createElement} from 'lwc';
import BitcoinEuroPrice from 'c/bitcoinEuroPrice';
describe('c-bitcoinEuroPrice', () => {
afterEach(() => {
while (document.body.firstChild) {
document.body.removeChild(document.body.firstChild);
}
});
it('fetches price', () => {
// Arrange
const testAmount = '8448.947391885';
const mockApiResponse = {
'data': {
'base': 'BTC',
'currency': 'EUR',
'amount': testAmount
}
};
fetch = global.fetch = mockFetch(mockApiResponse);
// Act
const priceUnderTest = createElement('c-bitcoinEuroPrice', {
is: BitcoinEuroPrice
});
document.body.appendChild(priceUnderTest);
// Assert
expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith('https://api.coinbase.com/v2/prices/spot?currency=EUR');
const displayPrice = priceUnderTest.shadowRoot.querySelector('lightning-formatted-number');
console.log('##### priceUnderTest', priceUnderTest);
console.log('##### displayPrice', displayPrice);
expect(displayPrice.value).toEqual(testAmount);
});
function mockFetch(mockApiResponse) {
return jest
.fn()
.mockImplementationOnce(() =>
Promise.resolve({
ok: true,
json: () => Promise.resolve(mockApiResponse),
jsonResponse: mockApiResponse
})
);
}
});
This fails with:
expect(received).toEqual(expected) // deep equality
Expected: "8448.947391885"
Received: undefined
34 | console.log('##### priceUnderTest', priceUnderTest);
35 | console.log('##### displayPrice', displayPrice);
> 36 | expect(displayPrice.value).toEqual(testAmount);
| ^
37 | });
38 |
but further down the log I see:
console.log
force-app/main/default/lwc/bitcoinEuroPrice/bitcoinEuroPrice.js:21
######## this.euroPrice: 8448.947391885
My hypothesis is that the test is not waiting for the asynchronous chain to complete before checking the value.
How can I make it wait? Or is there some other way I should check the value?