Unit testing

Learn how to write unit tests for your integration.

The JavaScript SDK includes a test mode that makes it easy to develop and test your integration by simulating SDK behavior without sending real API requests.

Here is what you need to check:

  • Make sure your tracking calls are triggered correctly
  • Verify you have defined fallbacks for your content
  • Ensure you are handling evaluation errors.

In the following sections, we will go through each of these points in detail.

Enable test mode

Since everything in the SDK is event-driven, the best way to test your integration is to listen for events and make assertions on them.

Even imperative methods — like identify, which identifies users, or user.edit, used to edit user profiles — are just syntactic sugar for triggering events. This approach simplifies testing because you do not have to rely on mocking, which usually results in brittle tests.

To make testing easier, the SDK provides a test mode that you can enable in your test environment.

Croct's mascot amazed
Automatic test mode detection

If you're using Jest  or any other test framework that sets the NODE_ENV=test, it should just work out of the box.

By default, the SDK auto-detects test environments based on the NODE_ENV.

To explicitly enable test mode, pass test as true when initializing the SDK.

Once enabled, the SDK uses a fake transport layer that simulates successful calls, so you do not need to mock the network requests.

Write tests

With test mode enabled, you can write assertions on the events triggered by your integration.

Suppose you want to check if your application correctly collects user interests. The code you want to test might look like this:

croct.user.edit()
.add('interest', 'tests')
.save()

This code triggers a userProfileChanged event with your changes to the user profile, which you can use to make assertions.

Here is an example of how you can write a test for this code using Jest :

Testing events
12345678910111213141516171819202122232425262728293031323334
import croct from '@croct/plug';
it('should add an interest to the user profile', async () => {
await croct.plug({
appId: '00000000-0000-0000-0000-000000000000',
test: true,
});
const listener = jest.fn();
croct.tracker.addListener(listener);
await croct.user.edit()
.add('interest', 'tests')
.save();
expect(listener).toHaveBeenCalledWith(
expect.objectContaining({
status: 'confirmed',
event: {
type: 'userProfileChanged',
patch: {
operations: [
{
path: 'interest',
type: 'add',
value: 'tests',
},
],
},
},
}),
);
});

You can find more details about the available events in the  Event reference.

Content retrieval testing

For testing if your content renders correctly, you can intercept the call to the fetch method and mock the response.

Here is an example of how to mock a successful response using Jest :

Testing content retrieval
12345678910111213141516171819202122
import croct from '@croct/plug';
it('should render the content', async () => {
const content = {
title: 'Banner title',
subtitle: 'Banner subtitle',
button: {
label: 'Button',
link: 'https://croct.com',
},
};
const fetchContent = jest.spyOn(croct, 'fetch');
fetchContent.mockResolvedValue({
content: content,
});
await render(); // Your rendering logic
expect(document.querySelector('h1').textContent).toBe(content.title);
});

To test your fallbacks, you can mock a failed response:

1234567891011
import croct from '@croct/plug';
it('should render the fallback content', async () => {
const fetchContent = jest.spyOn(croct, 'fetch');
fetchContent.mockRejectedValue(new Error('Failed to fetch content'));
await render(); // Your rendering logic
expect(document.querySelector('h1').textContent).toBe('Fallback title');
});

Query evaluation testing

To test if your queries are working as expected, you can follow the same approach as for content retrieval testing.

Here is an example of how to mock a successful response using Jest :

Greetings.test.jsx
123456789101112131415
import croct from '@croct/plug';
it('should render the content based on the query result', async () => {
const evaluateQuery = jest.spyOn(croct, 'evaluate');
evaluateQuery.mockResolvedValue({
result: true,
});
await render(); // Your rendering logic
expect(evaluatedQuery).toHaveBeenCalledWith('user is returning');
expect(document.querySelector('h1').textContent).toBe('Welcome back!');
});

To test your fallbacks, you can mock a failed response:

Greetings.test.jsx
12345678910111213
import croct from '@croct/plug';
it('should handle evaluation errors', async () => {
const evaluateQuery = jest.spyOn(croct, 'evaluate');
evaluateQuery.mockRejectedValue(new Error('Failed to evaluate query'));
await render(); // Your rendering logic
expect(evaluatedQuery).toHaveBeenCalledWith('user is returning');
expect(document.querySelector('h1').textContent).toBe('Welcome!');
});