Open artooras opened 5 years ago
I struggle to set it up as well. :thinking: A better example would be very appreciated!
Because you use mocksdk before declare, a mocksdk was declare at line 13. I suggest you to see tutorial at Tutorial: Integrating with jest and you don't necessary to use proxyquire when you use jest.
Thanks @Eji4h. I have removed proxyquire
, and my updated AppBody.test.js looks like this:
import React from 'react'
import {render} from 'react-testing-library'
jest.mock('./firebaseSetup.js', () => {
const firebasemock = require('firebase-mock')
const mockauth = new firebasemock.MockAuthentication()
const mockfirestore = new firebasemock.MockFirestore()
const mocksdk = new firebasemock.MockFirebaseSdk(
null, // RTDB
() => mockauth,
() => mockfirestore
)
const firebase = mocksdk.initializeApp()
const firestore = firebase.firestore()
const firebaseAuth = firebase.auth()
return firebase, {firebaseAuth, firestore}
})
describe('AppBody', () => {
it('renders', () => {
const {getByText} = render(
<AppBody
userID={'aaa'}
/>
)
expect(getByText('Today')).toBeInTheDocument()
})
})
The return statement of my mock matches that of firebaseSetup.js
, as per instructions. However, when I run my test, I get an error saying:
TypeError: this.dbData.onSnapshot is not a function
referring to this line in AppBody.js
:
this.dbDataUnsubscribe = this.dbData.onSnapshot(data => this.setState({data}))
So, what am I doing wrong?
The only library that needs mocking is the 'firebase/app'
one, so your mock should apply to that instead and simply return the mock SDK -- the 'instructions' (if one can call them that) are misleading:
import React from 'react'
import {render} from 'react-testing-library'
// Import firebase from your firebase init script:
import firebase from './firebaseSetup'
// Now mock 'firebase/app`:
jest.mock('firebase/app', () => {
const firebasemock = require('firebase-mock')
const mockauth = new firebasemock.MockAuthentication()
const mockfirestore = new firebasemock.MockFirestore()
return new firebasemock.MockFirebaseSdk(
null, // RTDB
() => mockauth,
() => mockfirestore
)
})
describe('AppBody', () => {
beforeAll(() => {
// Add some data to your mock firebase if you need to...
firebase.firestore().autoFlush()
firebase.firestore().collection('collectionId').doc('docId').set({foo: 'bar'})
})
it('renders', () => {
const {getByText} = render(
<AppBody
userID={'aaa'}
/>
)
expect(getByText('Today')).toBeInTheDocument()
})
})
Thanks, I think I'll give it another go and try your suggestion. I have since implemented a mock of my data-handling file, but maintenance is a bit of a pain in the bum... It would be much easier if I could simply mock the firebase bit.
Is there a way to set initial data for the tests? I couldn't really find that in the docs either.
AFAIK the only way to set initial data is to manually set each document, so:
const collectionRef = firebase.firestore().collection('collectionId');
ref.doc('docId').set({foo: 'bar'});
ref.doc('anotherDocId').set({foo: 'baz'});
// etc...
If you're only testing for one user and each user has its own document, I guess you'll only have one call to set()
.
@froddd : I tried your suggestion above, mocking the 'firebase/app' rather than my '@/firebase-setup', but it doesn't work for me; the mocking code runs but it doesn't seem to affect the actual firebase calls my source code makes -- they're still using the un-mocked firebase. For instance, in my test code firebase.firestore().autoFlush()
is not a function.
Any further hints? It would be great to see a fully worked example of firebase-mock with jest.
And if I try it a different way, I get firebase.apps.length
: Cannot read property 'length' of undefined. This seems to be because firebase
is now the mock object:
{ database: { [Function: MockFirebaseDatabase] ServerValue: { TIMESTAMP: [Object] } },
auth:
{ [Function: MockFirebaseAuth]
EmailAuthProvider: { [Function: EmailAuthProvider] PROVIDER_ID: 'password', credential: [Function] },
GoogleAuthProvider: { [Function: GoogleAuthProvider] PROVIDER_ID: 'google.com', credential: [Function] },
TwitterAuthProvider: { [Function: TwitterAuthProvider] PROVIDER_ID: 'twitter.com', credential: [Function] },
FacebookAuthProvider: { [Function: FacebookAuthProvider] PROVIDER_ID: 'facebook.com', credential: [Function] },
GithubAuthProvider: { [Function: GithubAuthProvider] PROVIDER_ID: 'github.com', credential: [Function] } },
firestore:
{ [Function: MockFirebaseFirestore]
FieldValue: { [Function: MockFirestoreFieldValue] delete: [Function], serverTimestamp: [Function] } },
storage: [Function: MockFirebaseStorage],
messaging: [Function: MockFirebaseMessaging],
initializeApp: [Function: initializeApp] }
which as you can see doesn't have an apps
member. I can work around that by checking for apps
in my init code, but then I'm back to this error:
TypeError: _myFirebase.db.collection(...).onSnapshot is not a function
so maybe firebase-mock just doesn't implement what I need?
Aha, I see #81 is about missing onSnapshot()
. That's core to how I use Firestore so I guess this won't work for me.
I think firebase has moved on a bit since the last commits to this mocking library -- I've just come across some more missing functionality, which I may create a PR for.
Just wanted to mention that the missing onSnapshot()
functionality is added in pull-request #130, but just hasn't been accepted yet.
In the mean-time, you can add that functionality by running npm install BrianChapman/firebase-mock#issue-81-onsnapshot
.
It's worked well so far in my project.
P.S. By the way, I agree with the others that the docs really need some improvement. The tutorials are... not really tutorials because they leave out important contextual information that let you produce actual working tests.
Best would be if there were a self-contained demo tutorial that is actually runnable.
In the meantime, the link to the setup tutorial page should be made more prevalent on the readme/homepage, and it should say: "Use the mocksdk
variable the same way you would use the var firebase = require("firebase/app");
variable"
Hi. While trying to set up
firebase-mock
in my project, I fail to 'connect the dots'. I have the following setup.firebaseSetup.js
AppBody.js
Now, the tricky part - AppBody.test.js
Now, obviously, my
test
file is incorrect. For one,mocksdk
is undefined in line 6. So, my question is, how do I setupfirebase-mock
correctly so that myAppBody
component at least renders and retrieves initial data?Thank you very much in advance!