I have made a React Native app which uses the Realm database. Opening this app and testing it manually does not result in any errors.
I have written tests for the Realm database, such as:
test("Create record in example table", () => {
realm.write(() => {
realm.create("ExampleTable", { "id": 1, "name": "Example", "notes": "Example Notes" });
});
const exampleRecord = realm.objects("ExampleTable")[0];
expect(exampleRecord.id).toBe(1);
expect(exampleRecord.name).toBe("Example");
expect(exampleRecord.notes).toBe("Example Notes");
});
These tests pass.
I have also written snapshot tests for different screens:
test("index.js Test", async () => {
const snapshot = renderer.create(<App />);
const snapshotJSON = snapshot.toJSON();
expect(snapshotJSON).toMatchSnapshot();
snapshot.unmount();
});
These tests fail. The error is:
Realm at path '/home/runner/work/app-name/app-name/default.realm' already opened on current thread with different schema.
In order to fix the error, I have attempted to write multiple different lines in the beforeEach()
and afterEach()
code blocks of the test file. However, these have not worked. For example, I have written the lines jest.clearAllMocks();
and Realm.delete()
in the afterEach()
code block. Through research, I have found the error may be because the tests are run in conjunction and Realm does not allow this. However, I have found no way to attempt to run the tests individually.
The only errors I have gotten besides these errors are:
● Console
console.error
The above error occurred in the <CreateWorkout> component:
at CreateWorkout (/home/runner/work/fitness-logger/fitness-logger/app/screens/create-workout/create-workout.js:10:63)
113 | const snapshotJSON = snapshot.toJSON();
114 | expect(snapshotJSON).toMatchSnapshot();
> 115 | snapshot.unmount();
| ^
To run the tests, I am using the command: npx jest --runInBand --detectOpenHandles --forceExit
Through research, I have found that I may need to mock the Realm database, although I am unsure how to do this. I am not using any Realm functions in my test file, although screens that I am taking snapshot tests of use the Realm database and use Realm functions
I have written the following mock in the test file:
jest.mock("realm", () => {
const mockObjects = jest.fn(() => {
const results = [];
results.filtered = jest.fn(() => { return results; });
return results;
});
function MockRealm() {
return {
"objects": mockObjects,
"write": jest.fn(),
"create": jest.fn(),
"deleteAll": jest.fn(),
"close": jest.fn(),
"addListener": jest.fn(),
"removeListener": jest.fn(),
};
}
MockRealm.open = jest.fn();
MockRealm.schema = [
{
"name": "Table",
"properties": {
"id": "int",
"property": "string",
},
"primaryKey": "id",
}
];
MockRealm.deleteRealmIfMigrationNeeded = true;
return MockRealm;
});
This stops the tests from failing. However, the tests still return the error from my try catch
block: Failed to get data from schema
. Moving this mock code into its own file in the __mocks__
directory causes the tests to fail.
Mock Realm in the testing file using the following code:
jest.mock("realm", () => {
const mockRealm = {
"objects": jest.fn(() => {
const results = [];
results.filtered = jest.fn(() => { return results; });
results.map = jest.fn(() => { return []; });
return results;
}),
"write": jest.fn((callback) => { return callback(); }),
"create": jest.fn(),
"deleteAll": jest.fn(),
"close": jest.fn(),
"addListener": jest.fn(),
"removeListener": jest.fn(),
};
mockRealm.open = jest.fn().mockResolvedValue(mockRealm);
mockRealm.schema = [
{
"name": "Table",
"properties": {
"id": "int",
"property": "string",
},
"primaryKey": "id",
}
];
mockRealm.deleteRealmIfMigrationNeeded = true;
return jest.fn(() => { return mockRealm; });
});
Write the snapshot tests using act
from react-test-renderer
:
test("index.js Test", async () => {
const snapshot = renderer.create(<App/>);
let snapshot;
await act(async () => {
snapshot = renderer.create(<App/>);
});
const snapshotJSON = snapshot.toJSON();
expect(snapshotJSON).toMatchSnapshot();
snapshot.unmount();
});