React Native with @realm/react - testing with Jest and @testing-library/react-native
Need help with setting up mock for the Realm.
In this example I’m trying to test my component ListOfPlayers to see if it renders a list, to do so I need to Mock the RealmProvider. But the problem is the Mocked Realm is always returning an Empty Object
instead of the data I’m writing to it.
If you have any insights on how to go about testing or I’m way of base, please feel free to share it thanks.
Hi @Kyle_Rollins is it possible you could help me out again ?
Below is the Test for the component ListOfPlayers.
import React from 'react';
import { render, act } from '@testing-library/react-native';
import ListOfPlayers from './ListOfPlayers';
import createMockRealm from '../../utils/Realm/MockRealm';
import { mockTeam, RealmProvider, schema, mockData, Realm } from '../../../__mocks__/realm/realm';
describe('ListOfPlayers', () => {
let realm;
let onChange;
beforeEach(async () => {
realm = await createMockRealm(schema, [mockTeam]);
onChange = jest.fn();
});
afterEach(() => {
if (!realm.isClosed) {
realm.close();
}
});
it('renders a list of players', async () => {
try {
const { getByText } = render(
<RealmProvider realm={realm}>
<ListOfPlayers player={{ name: 'player1' }} onChange={() => {}} />
</RealmProvider>
);
for (const player of mockData) {
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
expect(getByText(player.name)).toBeTruthy();
});
}
} catch (error) {
console.log(error);
}
});
});
Here is the utility mock function
import { Realm } from '@realm/react';
async function createMockRealm(schema, data) {
console.log('Creating mock Realm with schema:', schema);
console.log('Populating mock Realm with data:', data);
const config = {
schema,
deleteRealmIfMigrationNeeded: true,
inMemory: true,
path: 'mock.realm',
};
try {
const realm = await Realm.open(config);
console.log('Successfully created mock Realm:', realm);
data.forEach(item => {
realm.write(() => {
realm.create(item.name, item, true);
});
});
console.log(realm.objects('Team'), 'objects');
console.log('Finished populating mock Realm with data');
return realm;
} catch (error) {
console.log(error);
}
}
export default createMockRealm;
Here is the component
import React, { useContext, useState } from 'react';
import { ScrollView } from 'react-native';
import { RadioButton } from 'react-native-paper';
import { ThemeContext, UserContext } from '../../context/context';
import { useQuery } from '../../context/realmContext';
const ListOfPlayers = ({ player, onChange }) => {
const { colors } = useContext(ThemeContext);
const { userId } = useContext(UserContext);
const [selectedPlayer, setSelectedPlayer] = useState(player.name);
const team = useQuery('Team').filtered(`user_id == '${userId}'`)[0];
const players = team?.players;
return (
<ScrollView style={{ width: '100%', marginBottom: 20 }}>
<RadioButton.Group
value={selectedPlayer}
onValueChange={name => {
setSelectedPlayer(name),
onChange({
...player,
name: name,
});
}}>
{players.map(player => (
<RadioButton.Item
testID={'player-item' + player.name}
key={player._id}
labelStyle={{ color: colors?.primary }}
label={player.name}
value={player.name}
/>
))}
</RadioButton.Group>
</ScrollView>
);
};
export default ListOfPlayers;
Schema and realmProvider
import { createRealmContext } from '@realm/react';
import { Realm } from '@realm/react';
const schema = [
{
name: 'Player',
properties: {
name: 'string',
age: 'int',
_id: 'string',
},
},
{
name: 'Team',
properties: {
name: 'string',
user_id: 'string',
players: { type: 'list', objectType: 'Player' },
},
},
];
const mockData = [
{ name: 'player1', age: 21, _id: '1' },
{ name: 'player2', age: 22, _id: '2' },
{ name: 'player3', age: 23, _id: '3' },
];
const mockTeam = {
name: 'Team',
user_id: '123',
players: mockData,
};
const { useRealm, useQuery, useObject, RealmProvider } = createRealmContext({
schema,
deleteRealmIfMigrationNeeded: true,
inMemory: true,
});
export { useRealm, useQuery, useObject, RealmProvider, mockTeam, schema, mockData, Realm };