I'm going to test a method (using TypeScript language) to make sure it returns an array of a class.
Here is my code:
it('should return an array of Entity class', async () => {
expect(await service.getAll()).toBeInstanceOf(Entity[]);
});
But it shows the following error message at []
:
An element access expression should take an argument.
I'm going to test a method (using TypeScript language) to make sure it returns an array of a class.
Here is my code:
it('should return an array of Entity class', async () => {
expect(await service.getAll()).toBeInstanceOf(Entity[]);
});
But it shows the following error message at []
:
Share Improve this question edited Apr 2, 2022 at 12:51 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Apr 2, 2022 at 12:46 MohsenMohsen 1,1182 gold badges17 silver badges33 bronze badges 4An element access expression should take an argument.
- 1 You can't pass a type as a value, they're erased in pilation. – jonrsharpe Commented Apr 2, 2022 at 12:47
- So, how can I achieve my goal, making sure that the getAll method would return an array of Entity classes? – Mohsen Commented Apr 2, 2022 at 12:48
- 2 Is that a useful test? Do you not know what values you should be getting? It's unclear what the actual context is. – jonrsharpe Commented Apr 2, 2022 at 12:50
-
2
TypeScript already did that for you before runtime. Just add the return type to the
getAll
function, likegetAll(): Promise<Entity[]>
– CodinCat Commented Apr 2, 2022 at 12:59
1 Answer
Reset to default 7Since Jest tests are runtime tests, they only have access to runtime information. You're trying to use a type, which is pile-time information. TypeScript should already be doing the type aspect of this for you. (More on that in a moment.)
The fact the tests only have access to runtime information has a couple of ramifications:
If it's valid for
getAll
to return an empty array (because there aren't any entities to get), the test cannot tell you whether the array would have hadEntity
elements in it if it hadn't been empty. All it can tell you is it got an array.In the non-empty case, you have to check every element of the array to see if it's an
Entity
. You've saidEntity
is a class, not just a type, so that's possible. I'm not a user of Jest (I should be), but it doesn't seem to have a test specifically for this; it does havetoBeTruthy
, though, and we can useevery
to tell us if every element is anEntity
:it('should return an array of Entity class', async () => { const all = await service.getAll() expect(all.every(e => e instanceof Entity)).toBeTruthy(); });
Beware, though, that all calls to
every
on an empty array returntrue
, so again, that empty array issue raises its head.
If your Jest tests are written in TypeScript, you can improve on that by ensuring TypeScript tests the pile-time type of getAll
's return value:
it('should return an array of Entity class', async () => {
const all: Entity[] = await service.getAll()
// ^^^^^^^^^^
expect(all.every(e => e instanceof Entity)).toBeTruthy();
});
TypeScript will plain about that assignment at pile time if it's not valid, and Jest will plain at runtime if it sees an array containing a non-Entity
object.
But jonrsharpe has a good point: This test may not be useful vs. testing for specific values that should be there.