最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

react native - Snapshot Testing - Realm already opened on current thread with different schema - Stack Overflow

programmeradmin0浏览0评论

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.

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.

Share Improve this question edited Feb 4 at 13:35 user27793975 asked Jan 31 at 16:15 user27793975user27793975 197 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

From your description it definitely looks like it's an issue with running multiple tests in parallel. If you are using jest, you can use the --runInBand flag to run them all sequentially.

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();
});
发布评论

评论列表(0)

  1. 暂无评论