![]() ![]() This mistake is not caught by typescript because jest.Mock and jest.fn() are typed as a function from any to any, so the typescript compiler is willing to accept our mock as the predicate, even though its implementation returns the wrong type. This is because our mock predicate was not updated to return a promise as the interface requires, it still returns false. In our tests, however, this bug will not be caught even though in theory we have this case covered by the when the predicate is false test case. ![]() The code itself is still valid in terms of typescript but it is no longer correct - predicate now returns a promise, and a promise is always considered true, which means that predicateOrZero will not return 0 even if the predicate evaluates to false. For example, let's consider testing the following function: Having mock implementations decoupled from the interfaces they supposedly mimic makes it very easy to miss mocks during a refactor and could lead to a situation where some tests are not failing even when the code has a bug in the scenario under test. The problem begins when the code undergoes refactoring and some interfaces change over time. This is usually not a major problem when the test is first written, because it is fairly easy to create a mock of a specific function / interface. There is nothing preventing the mock function from returning the wrong type of answer. This worked great for a while, but the problem with using jest.fn() is that it creates a mock function that is completely decoupled from interface of the function being mocked. In our early tests we would create mock functions in the most straight forward way with jest.fn(). This has the benefit of being more readable and having a better error message if your test fails.Jest has a really nice framework for creating mock functions for unit tests and we use that framework quite extensively. If you catch yourself making assertions on the mock property directly, try to see if there’s already a built-in matcher for the assertion you’re looking for, maybe also combining them with utilities like expect.objectContaining. I encourage you to scroll through the expect reference to learn more about these features and how they compare to the ones that I didn’t cover in this post. It took me a long time to understand the nuances of these features, how to get what I want and how to even know what I want. Now, since our codebase is split across files, let’s start exploring mocking in the context of modules. Notice that we didn’t make assertions on the spy itself, we just temporarily altered Math.random’s behavior so we can make a predictable assertion on the code that it was affecting. Now when we run our tests, the following deterministic snapshot will be saved: exports = ` Array ` exports = ` Array ` We can call it, but nothing seems to happen. I assume you already know how to set up Jest? Good. Mock functions, are powerful and have many purposes-we can create new dummy functions, spy on existing functions, temporarily change their implementation, pass them around… usually in order to eventually make assertions on them, directly or indirectly. I would like to help you get familiar not only with mocking features in Jest, but these testing concepts in general. Add to that the fact that the term “mock” is ambiguous it can refer to functions, modules, servers etc. This can be an intimidating area for beginners, especially because at the time of this writing the Jest documentation on this subject is a bit spotty. Now I want to share that knowledge with you because it has been incredibly useful to me. For a long time I’ve been using only a small subset of them, but with experience I was able to gain a deeper understanding of these features. Spying on Functions and Changing Implementation.Spying on Functions and Changing Implementation Published on May 21st, 2019 Last modified on May 22nd, 2022
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |