Node.js和浏览器之间的测试行为不同

问题描述 投票:3回答:1

与Node.js相比,浏览器中的URL对象(在本例中为Chrome)的行为不同。因此,我在Node中运行时会通过测试,但行为在浏览器中不匹配。

为了演示,这是一个简单的parseURL函数,它试图从字符串中解析URL。如果它无法正确解析它,那么它会使用提供的字符串返回一个等同于Google搜索的网址。

function parseURL(query) {
  const formattedQuery = query.includes('://') ? query : `http://${query}`;

  try {
    return new URL(formattedQuery);
  } catch (err) {
    return new URL(`https://www.google.com/search?q=${encodeURIComponent(query)}`);
  }
}

还有一个简单的Jest测试来演示这个函数应该如何工作:

describe('parseURL', () => {
  it('accepts valid URL string', () => {
    expect(parseURL('https://example.com')).toEqual(
      new URL('https://example.com')
    );
  });

  it('prepends protocol when missing', () => {
    expect(parseURL('example.com')).toEqual(
      new URL('http://example.com')
    );
  });

  it('converts search queries', () => {
    expect(parseURL('example.com lol jk')).toEqual(
      new URL('https://www.google.com/search?q=example.com+lol+jk')
    );
  });
});

前两个测试具有Node.js和浏览器的匹配行为。大!

但是,第三个测试在Node.js中传递,即使行为在浏览器内部不匹配。具体来说,在Node.js中调用new URL('http://example.com lol jk')时,会引发错误。但是在浏览器中,不会引发错误,而是返回一个URL对象:

{
  href: "http://example.com%20lol%20jk/",
  origin: "http://example.com%20lol%20jk",
  protocol: "http:",
  username: "",
  password: "",
  hash: "",
  host: "example.com%20lol%20jk",
  hostname: "example.com%20lol%20jk",
  href: "http://example.com%20lol%20jk/",
  origin: "http://example.com%20lol%20jk",
  password: "",
  pathname: "/",
  port: "",
  protocol: "http:",
  search: "",
  searchParams: URLSearchParams {},
  username: ""
}

在使用这样的对象时,我如何确信我的测试反映了浏览器中实际发生的情况?

javascript node.js browser jestjs
1个回答
2
投票

问题是URL在实现之间是不一致的。

这是预期的行为

new URL('http://example.com lol jk')

抛出错误,它不是有效的URL。它在Node.js和Firefox中正确实现,但在Chrome中没有(在这里被称为“浏览器”)。

依赖于Jest中的Node.js实现是安全的。如果生产中需要一致性,则需要使用符合规范的实现URL替换whatwg-url

© www.soinside.com 2019 - 2024. All rights reserved.