realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.8k stars 577 forks source link

Cannot use both mocked realm and actual realm in a test #6122

Open Yupeng-li opened 1 year ago

Yupeng-li commented 1 year ago

How frequently does the bug occur?

Always

Description

If I mock realm in a test file, and then import the real realm in a particular test, it will give this error:

{{ TypeError: Cannot redefine property: Realm}}

The error is from this line. Object.defineProperty was called twice.

To reproduce the issue, see example below.

jest.mock('realm')

it('a test', () => {
    const Realm = jest.requireActual('realm')
    // ...
})

Stacktrace & log output

No response

Can you reproduce the bug?

Always

Reproduction Steps

No response

Version

12.1.0

What services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

Mac OS 13.5.1 (22G90)

Build environment

Which debugger for React Native: ..

Cocoapods version

1.12.1

kneth commented 1 year ago

@Yupeng-li Mocking Realm in Jest isn't trivial. You might want to seek inspiration in https://github.com/realm/realm-js/issues/370#issuecomment-1464892940

Yupeng-li commented 1 year ago

Hi @kneth , thank you! My issue isn't about how to mock realm, but realm module throws when it's imported multiple times. The sample code above shows the scenario when it could be imported twice. Our use case is slightly different. We use a jest custom matcher which imports Realm. Our tests also import realm, so the module is imported twice.

I temporarily fixed the issue I reported but then I got errors like:
Error: Expected value to be an instance of List, got an instance of List Error: Illegal constructor: Results objects are read from managed objects only.

It seems that assertion is checking instance type against two copies of the module. We didn't have the issue with Realm v11, so I am wondering if this is something you could fix?

Best regards

Yupeng-li commented 1 year ago

There is a more common scenario. If I mock a file that imports Realm, the TypeError will be thrown. Please let me know if you need a min repo.

// functionB.ts

import Realm from 'realm' 

export const functionB = () => {
    console.log('function B', typeof Realm)
}
// some.test.ts
import Realm from 'realm' // this is required to reproduce the issue 
import { functionB } from './functionB'

jest.mock('./functionB') // This crashes the test because of the error: TypeError: Cannot redefine property: Realm

it('a test', () => {
    console.log('ss', typeof Realm) // This could be the code pre-populating data to realm, e.g. realm.create(...)
    functionB()
})
a396901990 commented 11 months ago

I have the same issue, the test stopped working since upgrading to realm v12.3.0

liamjones commented 6 months ago

Hi @kraenhansen I'm going through a bunch of upgrades on our apps atm (RN, 3rd-party deps, etc) and I was just wondering if there was any news on this issue yet? It's our remaining blocker to upgrade from Realm 11 to 12.