我需要测试一个在浏览器中打开一个新选项卡的功能

openStatementsReport(contactIds) {
  window.open(`a_url_${contactIds}`);
}

我想模拟窗口的打开函数,这样我就可以验证正确的URL被传递给打开函数。

使用笑话,我不知道如何模拟窗口。我试着设置窗口。使用mock函数打开,但这种方式不起作用。下面是测试用例:

it('the correct URL is called', () => {
  window.open = jest.fn();
  statementService.openStatementsReport(111);
  expect(window.open).toBeCalled();
});

但是它给出了误差

expect(jest.fn())[.not].toBeCalled()

jest.fn() value must be a mock function or spy.
    Received:
      function: [Function anonymous]

我应该对测试用例做什么?


当前回答

我们也可以在setupTests中使用global来定义它:

// File 'setupTests.js'
global.open = jest.fn()

并在实际测试中使用global调用它:

// File 'yourtest.test.js'
it('the correct URL is called', () => {
    statementService.openStatementsReport(111);
    expect(global.open).toBeCalled();
});

其他回答

我找到了一个简单的方法:删除和替换

describe('Test case', () => {
  const { open } = window;

  beforeAll(() => {
    // Delete the existing
    delete window.open;
    // Replace with the custom value
    window.open = jest.fn();
    // Works for `location` too, eg:
    // window.location = { origin: 'http://localhost:3100' };
  });

  afterAll(() => {
    // Restore original
    window.open = open;
  });

  it('correct url is called', () => {
    statementService.openStatementsReport(111);
    expect(window.open).toBeCalled(); // Happy happy, joy joy
  });
});

我们也可以在setupTests中使用global来定义它:

// File 'setupTests.js'
global.open = jest.fn()

并在实际测试中使用global调用它:

// File 'yourtest.test.js'
it('the correct URL is called', () => {
    statementService.openStatementsReport(111);
    expect(global.open).toBeCalled();
});

你可以测试它:

describe('TableItem Components', () => {
    let open_url = ""
    const { open } = window;
    beforeAll(() => {
        delete window.open;
        window.open = (url) => { open_url = url };
    });
    afterAll(() => {
        window.open = open;
    });
    test('string type', async () => {
        wrapper.vm.openNewTab('http://example.com')
        expect(open_url).toBe('http://example.com')
    })
})

在我的组件,我需要访问window.location.search。这是我在Jest测试中所做的:

Object.defineProperty(global, "window", {
  value: {
    location: {
      search: "test"
    }
  }
});

如果窗口属性在不同的测试中必须不同,我们可以将窗口模拟放到函数中,并使其可写,以便在不同的测试中重写:

function mockWindow(search, pathname) {
  Object.defineProperty(global, "window", {
    value: {
      location: {
        search,
        pathname
      }
    },
    writable: true
  });
}

并在每次测试后重置:

afterEach(() => {
  delete global.window.location;
});

你可以试试这个:

import * as _Window from "jsdom/lib/jsdom/browser/Window";

window.open = jest.fn().mockImplementationOnce(() => {
    return new _Window({ parsingMode: "html" });
});

it("correct url is called", () => {
    statementService.openStatementsReport(111);
    expect(window.open).toHaveBeenCalled();
});