Writing tests
For the final lesson on the JavaScript side of things, we will learn how to write unit tests. We will focus on how to write tests for our MobX stores since this is where a lot of the heavy logic of the app will reside.
Introducing Jest#
Jest is the default testing framework for React and React Native apps, and it's already bundled for you when you created your app. The init
script should have created a __tests__
folder for you at the root of the project, and you could place all your tests into that folder, but I prefer to colocate them next to the files.
Let's start by creating a UI.store.spec.ts
next to our UI.store.ts
file.

Before writing our first test, let us set up the necessary scaffolding:
// src/stores/UI.store.spec.ts
import {createUIStore} from './UI.store';
describe('UI Store', () => {
let UIStore: ReturnType<typeof createUIStore>;
const rootMock: any = {
api: {},
};
beforeEach(() => {
UIStore = createUIStore(rootMock);
});
});
First we import our createUIStore
function. We then create a describe
block (describe
is part of Jest). A describe block is nothing more than a way to group related tests together. It will also be used to format the output of the tests.
In the body of the function passed to the describe
block we will declare a UIStore variable, and we will use this variable between tests to instantiate a clean UI store object. Next we create a mock root store. The benefit of creating our store as a factory function instead of exporting an instance is that we can pass a mocked root object (this is called dependency injection, if you already did not know about it).
We then have another specific Jest function called beforeEach
which will run before each test in the nearest scope (either inside the describe block or the entire file). We pass a function to it, and inside we call our createUIStore
function along with our root mock, that way in each test we have a clean instance of our store to write our tests against.
Writing tests#
We can finally begin creating some tests. First, let's create a test to verify the initial state of the store:
it('is correctly initialized', () => {
expect(UIStore.books).toHaveLength(0);
expect(UIStore.uppercasedBooks).toHaveLength(0);
});
The it
function from Jest creates a unit test for us - we pass it a function where we can manipulate our UIStore
object and create expectations with the expect
function. Now that we have a basic test running we can move to the more complex functionality.
You can run all of your project tests from your console. It will run and print the output of your tests.
# On the projects directory
yarn test
Let's create a test that calls the fetchBooks
function and makes sure the store is in a correct state. Let's try to do a naive implementation first:
it('fetches and stores books', async (done) => {
expect(UIStore.books).toHaveLength(0);
await UIStore.fetchBooks();
expect(UIStore.books).toHaveLength(3);
done();
});
Since our fetchBooks
functions is async we need to modify the function we pass to the test by making it async. We also added the first param done
, which is a utility callback for async functions that might not cleanly exit. Inside our test we first check that the book array is empty, then we call and await the fetchBooks
call. After the store has fetched the books, the book array should contain some books. Finally we call done
to let Jest know this test is done.
This page is a preview of Building React Native Apps for Mac