/images/avatar.jpg

Jorge Ortiz-Fuentes' DevBites

Rust unit testing test doubles: fakes

In my previous articles, I have been writing about test doubles. I explained what they are and the different types we can use. I described some scenarios and wrote the test doubles that would help us test the code: dummies, stubs, spies, and mocks. Only one type was left: fakes. Let's look at those now.

Fakes are tests doubles that implement a simplified version of a task or computation. They come in handy when the real thing is slow or complicated. Ciphering messages is usually an expensive task, and we don't want our tests to take longer than they should. So, instead of performing the (real) encryption, we will have a fake that makes a simpler text manipulation.

Rust unit testing: mock test doubles

This is the third article on test doubles. So far, I have covered stubs –that are used to control the responses to the methods of the type they double,– dummies –that fill "holes" that are required for some tests without any functionality,– and spies –that remember the interactions with the type they double. It is time to talk about the face of the band: mocks.

For the price of a mock, you get everything that was included in a stub and a spy, plus some intelligence. And I am not talking about AI. Mocks are a little smarter than stubs and spies, because they include the code to verify themselves. All those ugly asserts that used the fields in the guts of the spies will be no longer necessary.

Rust unit testing: spy and dummy test doubles

In my last article, I explained what test doubles are and why we need them. In this one, I am going to focus on two different types of test doubles: the spy and the dummy.1

A spy is a test double that remembers if its methods have been invoked and the arguments used with each invocation. It spies on the activity of the caller instance. A dummy does nothing, but it is required to create or use something else.

Rust unit testing: test doubles & stubs

Unit testing is about writing tests for individual units (Duh!), most frequently these units are the types that we define in our code, i.e., structs / enums / unions, or first-class functions. But the types that we want to test usually have dependencies on other types and we would like to test them in isolation without having to worry about the details of those dependencies. That's why you need test doubles.

Rust unit testing: add-ons

In my last article, I wrote about some builtin features of the tools that come with our Rust setup. They help you to produce better documentation, have more control of the tests you run, and debug tests/code when needed. The Rust ecosystem is very rich and active and people with other needs have contributed with really useful tools.

Today, I will write about two tools that might come in handy for you sooner or latter. There are many details in the following paragraphs, so fasten your USB-C cable and get ready!

Rust unit testing: builtin tools

As many other modern languages, regarding testing, Rust comes with batteries included. As you have seen in the previous articles of this series, you don't need to take any extra steps to be able to write and run unit tests for your code. It is clear where you have to put them, how to run them, and even cargo has a subcommand for finding and running them, and reporting the results. Could we ask for more?