DEV Community

Cover image for Don't use fixtures in Cypress and unit tests- use factories

Don't use fixtures in Cypress and unit tests- use factories

Dan Greene on September 18, 2020

Unit tests are great... when they work dependably! In fact, there's an old saying that "a bad test is worse than no test at all." I can attest that...
Collapse
 
elihimself profile image
Eli Tamošauskas • Edited

Loving every bit of this! Thanks Dan!

Collapse
 
dgreene1 profile image
Dan Greene

Thanks you so much for the positive energy. It certainly has been a pattern that has worked well for the teams at our company in the time since we adopted the pattern.

Collapse
 
arcigo profile image
Armando Cifuentes González • Edited

Just for curiosity.- To avoid this error Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'., without using your library, can I solve it by adding the ! at the end of the property I want to use (I mean, something like this: const field: string = faker().field!;)?

Collapse
 
dgreene1 profile image
Dan Greene

To avoid that error you have to check to see that the variable is not undefined.

So

if(yourVariable === undefined){
  throw new Error (an error message explaining why this is happening);
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
arcigo profile image
Armando Cifuentes González

Ok!

Collapse
 
bmitchinson profile image
Ben Mitchinson

Great write up, thanks for taking the time to describe the issue. Just ran into similar issues, and this provides clear fixes + is a great reference for my team.

Collapse
 
dgreene1 profile image
Dan Greene

Thank you kindly Ben. And please ask them to share with others. I’d like to see this become a standard within the TS Cypress community.

Again, it’s so generous of you to say thank you. Isn’t dev.to such a wonderful community? :)

Collapse
 
josh68 profile image
Josh Schneider

Very nice article, @dan

All they were thinking about is that they need to test a feature that involves a deleted user. So they add deleted: false to the generalUser object.

Is this supposed to read "So they add deleted: true..." or am I confused?

Collapse
 
chimchim2 profile image
Chim

🔥🔥🔥

Collapse
 
mareru profile image
Marijana Rukavina

Thanks Dan for writing this article. It sounds like a direction I would like to go to. I have one question though. How would you solve for Typescript the fact that cypress ui tests need to run on different environments? Meaning you would have to create/load test data objects with different values for different environments. I would appreciate if you could share your thoughts about it. Thanks 😊

Collapse
 
dgreene1 profile image
Dan Greene

My apologies for not seeing this question sooner. So I would first ask thy you would need different data for mocked tests. Generally mocked tests are designed to test the "shape" of your data, not necessarily real data. As where end-to-end (e2e) tests would rely on both the shape and the content of the data and would therefore not utilize mock data (or factories) at all.

But if you still choose to mock different data per environment, I would consider simply clarifying that in your tests.

let user: IUser | null = null;
if(process.env.NODE_ENV === 'production'){
  user = makeFakeUser({userName: 'John'});
} else if(process.env.NODE_ENV === 'staging'){
  user = makeFakeUser({userName: 'Susan'});
}
// Assert so that the user variable can no longer be seen as null
if(!user){
  throw new Error(`unable to initialize mock user since NODE_ENV was invalid`);
}
// the rest of your test
Enter fullscreen mode Exit fullscreen mode