In my Angular project, I have decided to remove jasmine and karma and use jest and testing-library. I have decided to apply my test policy under the "case of use" concept. It means: My tests are made on the component and I only will mock the infrastructure layer (in this case, the requests of the API --> HttpClient.
For this reason, I have decided to use Testbed to prepare my component and use HttpClientTestingModule for mocking the requests.
Everything goes well except if I try to use the mocks of HttpClientTestingModule, asynchrony of @angular/core/testing
(fakeAsync()
and tick()
) and testing-library at the same test.
So, I have this tests that work:
function mockGet(url: string, response: object): void {
const httpMock = TestBed.inject(HttpTestingController)
const mockRequest = httpMock.expectOne(url)
mockRequest.flush(response)
}
describe('MY COMPONENT', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [],
imports: [HttpClientTestingModule, MyModule],
}).compileComponents()
await TestBed.compileComponents()
})
describe('when render component', () => {
it('call to endpoint to get data', fakeAsync(async () => {
await render(OrdersComponent, {})
mockGet('/status', {
detail: 'not recalculating',
})
tick()
mockGet('/data', [])
}))
})
describe('When is recaltulating', () => {
it('show recalcualting loader', async () => {
await render(OrdersComponent, {})
mockGet('/status', {
detail: 'recalculating',
})
expect(await screen.findByText('Recalculating')).toBeInTheDocument()
})
})
})
As you can see, I have one test using a fakeAsync()
and tick()
and other test with testing-library.
But, if I try to add one test with fakeAsync and tick and testing-library:
[...]
describe('When is not recalculating', () => {
it('show data', fakeAsync(async () => {
const { detectChanges } = await render(OrdersComponent, {})
mockGet('/status', {
detail: 'not recalculating',
})
tick()
mockGet('/data', 'some_text_from_data')
expect(await screen.findByText('some_text_from_data)).toBeInTheDocument()
//discardPeriodicTasks()
//detectChanges()
//flush()
}))
})
[...]
This is giving me an error: "1 periodic timer(s) still in the queue."
I have tried to use discardPeriodicTasks()
(and flush()
), but nothing fix this. Even, I have tried some changes using detectChanges or waitFor from testing-library, but I can't get the test to turn green.
Also, I don't know if this is relevant, but I show it for your information:
Within the hours I've been trying to fix this, I've done many variations, and on more than one occasion I get this error:
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Zone'
| property '_zoneDelegate' -> object with constructor '_ZoneDelegate'
--- property 'zone' closes the circle
at stringify (<anonymous>)
at messageParent (node_modules/jest-worker/build/workers/messageParent.js:33:19)
PD: it's my first post on Stackoverflow, I hope I have made myself clear in my explication.
PD': sorry for my level of english xD