Jest 模拟 documentElement lang 属性

And*_*4x4 5 javascript unit-testing typescript jestjs

我正在尝试为我的测试操作 documentElement lang 属性。并且无法弄清楚我怎么能做到这一点。我已经尝试在 Jest 配置中定义 setupFiles - 这让我有可能定义它并且没有选择为不同的测试更改它 - 如此处所述:Mocking `document` in jest

部分测试代码如下所示:

const lang: string = document.documentElement.lang ?
      document.documentElement.lang : Constraints.DEFAULT_LANGUAGE;
Run Code Online (Sandbox Code Playgroud)

测试是这样的:

   test('should pass `en` language when document hasn`t any specified', () => {
    const spy = jest.spyOn(window.document, 'documentElement', 'get');
    expect(spy).toHaveBeenCalled();
  });
Run Code Online (Sandbox Code Playgroud)

并使用setupFiles

Object.defineProperty(document, 'documentElement', {
    writable: true,
    configurable: true,
    value: document.createElement('document')
});
Run Code Online (Sandbox Code Playgroud)

当我有 setupFiles 时,我收到错误: Property documentElement does not have access type get

但是当我尝试在没有setupfile.js配置的情况下监视它时,永远不会调用 spy。

编辑

更清晰的例子是我想要实现的目标:

    const lang: string = document.documentElement.lang ?
      document.documentElement.lang : Constraints.DEFAULT_LANGUAGE;
    component.src = `/${lang}/mysite`;
Run Code Online (Sandbox Code Playgroud)
test('should pass `de` language when document has one specified', () => {
    const spy = jest.spyOn(window.document, 'documentElement', 'get');
    const mockElement = document.createElement('document');
    mockElement.lang = 'de';
    spy.mockReturnValue(mockElement);
    expect(component.src).toContain('/de/');
  });
Run Code Online (Sandbox Code Playgroud)

在测试中我得到:

expect(received).toContain(expected) // indexOf

    Expected substring: "/de/"
    Received string:    "http://localhost/en/mysite"

Run Code Online (Sandbox Code Playgroud)

Tug*_*lik 8

好吧,您已经快到了,但是当您访问document.documentElement.lang属性时,get 访问器已被触发。所以你应该像下面一样定义该对象;

Object.defineProperty(document, 'documentElement', {
    configurable: true,
    get () {
        return document.createElement('document');
    },
});
Run Code Online (Sandbox Code Playgroud)

在你的测试中;

在 Expect 行之前,您应该添加此行以触发 getter 并使间谍被调用。

window.document.documentElement.lang;
Run Code Online (Sandbox Code Playgroud)

编辑

忘记上面的事情吧。

只需删除您的设置代码块,我认为您不需要间谍或其他东西。

创建一种将语言设置为常量的方法。然后测试该方法而不是测试getdocumentElement 的操作。

在调用您的方法之前,请使用下面的代码来设置 lang 属性。(想象你有语言方法)

test('should return `de` language when document has one specified', () => {
    Object.defineProperty(document.documentElement, 'lang', { value: 'de', configurable: true });

    expect(component.language()).toBe('de');
});
Run Code Online (Sandbox Code Playgroud)