16
votes

I'm trying to mock out the window object for a component I'm using with just the four libraries listed above.

I know it can be done with JSDom but the client is against using it. Based on my research simply doing sinon.stub(window,'location') should work but when I run my tests I still get Window undefined in my component.

Currently the component is called within the render return {window.location.host}

any thoughts to what I am doing wrong to get sinon to stub out that one piece. Once I stub out that piece then I can focus on testing the other parts of that component that have nothing to do with window.

My Test Method:

import React from 'react';

import { shallow } from 'enzyme';
import chai from 'chai';
chai.should();
import sinon from 'sinon';

import BillingStatementRow from '../BillingStatementRow';

describe('Test <BillingStatementRow /> Component', function() {

    context('Function Testing', function() {

        it('Test - onFieldChange - Make sure it handles NaN', function() {

            var e = {target: {value: NaN}};

            var window = { location : { host : "..." } };

            var mockedOnChange = sinon.spy();

            const wrapper = shallow (
                <BillingStatementRow slds={''} key={'1'}
                    Id={'1'} inputValue={'0'} salesInvoice={'SIN0001'}
                    invoicedAmount={1000} duedate={'1461628800000'}
                    outstandingBalance={1000} receiptRemaining={1000}
                    amountAllocated={1000} onChange={mockedOnChange.bind(this,'BS0001')} />
            );

            wrapper.instance().onFieldChange('amountAllocated', e);
            wrapper.update();


        })


    });

});
1
I assume that you have declared window first (as an empty object or something)? Also, is it available everywhere (i.e. is it a global)? EDIT: hmm never mind, window.location isn't a function anyway, and Sinon can only stub functions. Still, what exactly do you want to test? Why not just declare a global window = { location : { host : "..." } }? - robertklep
Yep window is declared first yet it still gives me window is not defined. - DimlyAware
Try global.window = { location : ... } instead. - robertklep
Thank you - it looks like it worked. - DimlyAware

1 Answers

30
votes

Sinon stubs/spies/mocks only work with functions. In this case, you're trying to mock a global (nested) variable, for which Sinon isn't the right tool.

Instead, just like in a browser, you can create a global object that mocks just the right amount of window to work with your component, which is easy because it only accesses window.location.host.

So before instantiating the component, declare the following:

global.window = { location : { host : 'example.com' } };