Integration Testing of fetch module

Hey meteor community,

we are developing a meteor app with integration tests that follows the testing guide from meteor, but we are now struggling with an unfortunate specific testing issue after migrating our code from a meteors HTTP-package to the fetch-package:

How is it possible to stub meteors fetch package with chai spies / sandbox in integration tests?

If we try to setup the test mocks the same way as the HTTP.call method we end up in an error, that chai can’t mock the fetch es6 module, cause it’s not like a real JS object and the "hasOwnProperty function is missing. Here is the exact error message, while running a test:

TypeError: object.hasOwnProperty is not a function

Here is a minimal code sample how we do the integration test and causing this error:

a server-side module using the fetch.package
“services/fetch-something.js”:

import { fetch } from 'meteor/fetch';

const fetchSomething = (url) => {
    return fetch(url, 
           {
               method:'GET'
               ...fancy authorization headers and stuff
           }
    )
 }

export default fetchSomething ;

and now our integration test module for fetchSomething (e.g. testing of correct headers or correct server errors, whatever)
“services/fetch-something.spec.js”:

import * as fetchModule from 'meteor/fetch';  // using this kind of import to avoid "read-only" exception
import chai from 'chai';
import spies from 'chai-spies';

import fetchSomething  from './fetch.something.js';

chai.use(spies);

const sandbox = chai.spy.sandbox();

const mockFetch = (mock) => {
        sandbox.on(fetchModule , 'fetch', mockFn); 
}

describe('FetchSomething Testing', () => {
     if('simple mocking test', () => {
           mockFetch(() => console.log);    // <--- throws exception
           fetchSomething('https://does.not.get/to/this/line-anyway');
     });
});

It’s clear for us, that this particular code sample is also testable in a simple unit test where mocking is setup pretty easy (e.g with Jest). But in our real use case the fetch-call is just a part of a whole communication protocol that is required to be tested together with a database system (so be part in the integration testing).

We appreciate any advice or discussion link how we can handle this sample use case of an import-function-mocking.

Looking forward to here your thoughts!
Cheers,
Fabian

1 Like

I’ve had some success mocking some other Meteor functions using testdouble - npm

td.replace(Meteor, 'userId', () => context.userId)

I’m not sure if it will work in your case but it’s worth trying!

1 Like

hello @hexsprite,

thanks for your reply. We use that kind of mocking already somewhere else, but that requires an object that’s been mocked. It does not work in our case, cause we we have a named import of a function.

So the difference is:

import { Meteor } from 'meteor/meteor';

// "Meteor" is an object that you can mock - or a part of that object (e.g. "userId" function)

vs

import { fetch } from 'meteor/fetch';

// "fetch" is the function itself you want to mock

Have you just tried ‘manually’ replacing the object?

eg.

import * as fetchModule from 'meteor/fetch'

fetchModule.fetch = function() { ... }

Just curious if that would work for you…

hello @hexsprite ,

sry for my belated reply. Your suggestion was the way we tried the mocking the first place (see import in the question).

We ended up using a workaround. We integrated nock in our integration tests.

 nock(/url/)
            .get('/route')
            .reply(200, {
                body: JSON.stringify({
                   mocked: "payload"
                }),
            });