2016-12-12 9 views
2

Я пытаюсь написать тесты для моих проектов веб-компонентов в шутку. Я уже использую babel с предустановкой es2015. Я сталкиваюсь с проблемой при загрузке js-файла. У меня есть следующий код, где document объект имеет currentScript объект. Но в тестовом контексте это null. Поэтому я думал о насмешливости. Но jest.fn() на самом деле не помогает. Как я могу справиться с этой проблемой?Издевательская `document` в шутке

Кусок кода, в котором шутка не работает.

var currentScriptElement = document._currentScript || document.currentScript; 
var importDoc = currentScriptElement.ownerDocument; 

Тестовый чехол Я написали. component.test.js

import * as Component from './sample-component.js'; 

describe('component test', function() { 
    it('check instance', function() { 
    console.log(Component); 
    expect(Component).toBeDefined(); 
    }); 
}); 

Ниже ошибка брошена шутя

Test suite failed to run 

    TypeError: Cannot read property 'ownerDocument' of null 

     at src/components/sample-component/sample-component.js:4:39 

Update: Согласно предложению от Andreas Köberle, я даже добавил глобальный вар и попытался насмешливо, как следующий

__DEV__.document.currentScript = document._currentScript = { 
    ownerDocument: '' 
}; 
__DEV__.window = { 
    document: __DEV__.document 
} 
__DEV__.document.registerElement = jest.fn(); 

import * as Component from './arc-sample-component.js'; 

describe('component test', function() { 
    it('check instance', function() { 
    console.log(Component); 
    expect(Component).toBeDefined(); 
    }); 
}); 

Но не повезло

Обновление: Я даже пробовал код выше __dev__. Также, установив документ как глобальный.

+1

Вы пытались использовать 'global.document'? –

+0

Да .. я пробовал это..не удачи .. – thecodejack

+0

Так что я в основном использовал jsdom как 'const jsdom = require ('jsdom'); const documentHTML = '

'; global.document = jsdom.jsdom (documentHTML); ' И после этого я придерживаюсь всего, что хочу, для документа и его доступных в моих тестах. –

ответ

5

Я разрешил это с использованием setUpFiles недвижимости в шутку. Это будет выполняться после jsdom и перед каждым тестом, который идеально подходит для меня.

Set SetupFiles, в Jest конфигурации, например .:

"setupFiles": ["<rootDir>/browserMock.js"] 


// browserMock.js 
Object.defineProperty(document, 'currentScript', { 
    value: document.createElement('script'), 
}); 

Идеальная ситуация нагружать webcomponents.js в polyfill в jsdom.

2

я мог бы решить эту проблему, используя тот же global области видимости модуля на nodejs, установив документ издеваться документа, в моем случае, getElementsByClassName:

// My simple mock file 
export default { 
    getElementsByClassName:() => { 
     return [{ 
      className: 'welcome' 
     }] 
    } 
}; 

// Your test file 
import document from './name.component.mock.js'; 
global.document = { 
    getElementsByClassName: document.getElementsByClassName 
}; 
+0

yep..that делает, но его очень простой usecase ... в webcomponents.js у нас есть большой набор API взаимосвязанных. Издеваться над ними - одна из задач ... – thecodejack

+0

Но в вашем случае, что вам нужно, чтобы точно насмехаться? –

0

Если как я вы хотите, чтобы издеваться документ не определен (например, для стороны сервера/на стороне клиента испытаний) я был в состоянии использовать object.defineProperty в моих тестовых наборах без использования SetupFiles

Пример:

beforeAll(() => { 
    Object.defineProperty(global, 'document', {}); 
})