'Unit test Google tag manager Initialization and events
I am trying to Unit test Google tag manager code in React project. Following is what I want to test precisely:
- If Google tag manager is initialized with given properties
- Check if events are getting fired fine and are being pushed to DataLayer in window object
Sample component with gtm initialization in useEffect:
useEffect(() => {
if (!isLoading) {
try {
let dataLayer = {
userProject: 'project-ui'
}
if (typeof data.id !== 'undefined') {
dataLayer = {
userId: data.id,
userProject: 'project-ui'
}
}
const tagManagerArgs = {
gtmId: process.env.REACT_APP_GTAG_TRACKING,
dataLayer
}
TagManager.initialize(tagManagerArgs)
} catch (e) {/**/ }
}
}, [isLoading])
I am trying to cover mutation of if (typeof data.id !== 'undefined') as well is !isLoading here. This is the exact goal.
please note data is coming from react-query:
const { isLoading, data } = useQuery([USER_TRACKING_ID], () =>
getLoggedInUserProfile())
Code I have written so far for Unit Testing:
test("Ga loads", async () => {
window.dataLayer = {
push: jest.fn().mockImplementation(config => {
config.eventCallback()
}),
}
render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<Provider store={store}>
<MainContainer />
</Provider>
</BrowserRouter>
</QueryClientProvider>
)
const { result, waitFor } = renderHook(() => useCustomHook(), {
wrapper: createWrapper()
})
await waitFor(() => result.current.isSuccess)
console.log('test data: ', result.current)
console.log('data layer data: ', window.dataLayer) // this is throwing undefined
const eventSpy = jest.spyOn(TagManager, 'initialize')
expect(result.current.data).toEqual({
"employeeId": "797979878",
"name": "UserFirstName lastName",
"userEmail": "[email protected]",
"loginTime": 1652073402000
})
expect(window.dataLayer.push).toHaveBeenCalled()
// expect(eventSpy).toHaveBeenCalled()
})
Sample code for one of the dataLayer push I want to test:
const messageBoardhandler = () => {
try {
dataLayer.push({
event: 'NotificationBoard',
userId: queryClient.getQueryData('USER_TRACKING_ID').id,
category: 'MessageBoard',
action: 'NotificationClicked',
label: 'NotificationIcon',
value: ''
})
} catch (e) { /* */ }
dispatch(appCategoryAction.setAppCategoryFlyer(false))
if (!pinMessageBoard) {
dispatch(messageBoardActions.setMessageBoardChatFlyer(true))
}
}
I want to understand first of as I tried to mock the react-query for data, how shall I render the component and in what order, and how can I get this initialization to be tested.
I tried taking multiple approach:
- Tried directly asserting on Data Layer array from window which turns out is undefined.
- Tried using jest mock to import TagManager library that I am using to load gtag and mock TagManager.initialize and no luck.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
