开玩笑;如何在字符串上测试 JSON.parse 会成功

Posted

技术标签:

【中文标题】开玩笑;如何在字符串上测试 JSON.parse 会成功【英文标题】:jest ; how to test JSON.parse on a string will succeed 【发布时间】:2018-09-05 14:25:39 【问题描述】:

我正在为 API 编写单元测试。

如果我这样做:

const apiResponse:object = JSON.parse(body)
expect(apiResponse).toHaveProperty('error')

并且 API 没有返回 JSON,然后我得到类似:

SyntaxError:JSON 中位置 0 的意外标记 p 在 JSON.parse()

我希望我的测试失败,而不是在我的测试中出错。

我能做的一个有趣的测试是什么;我收到的这个字符串是否可以解析为有效的 JSON?

【问题讨论】:

将其包装在 try/catch 中。除了解析它之外,没有内置的测试 json 有效性的方法。 在 @Adriani6 上扩展 更改代码以将解析包装在 Try/Catch 中,然后在解析失败时返回异常,然后 Jest 可以使用错误的 JSON 测试异常,并进行另一个正常测试获得良好的 JSON 数据。 【参考方案1】:

您可以简单地使用 Jest's .not.toThrow() 断言 JSON 解析不会引发错误。

这是我做的一个例子,它断言一个对象可以被解析为有效的 JSON:

it("Produces metadata object that can be parsed to valid JSON", () => 
    const meta = articleMetaData(article);

    const parseJson = () => 
        const json = JSON.stringify(meta);
        JSON.parse(json);
    ;

    expect(parseJson).not.toThrow();
);

例如,如果对象具有圆形结构:

var obj = 
  a: "foo",
  b: obj

测试会失败:

Expected the function not to throw an error.
Instead, it threw:
    TypeError: Converting circular structure to JSON

【讨论】:

【参考方案2】:

我通过添加一个我发现 here 的辅助函数解决了这个问题

const isJSON = (str:string) => 
    try 
        const json = JSON.parse(str);
        if (Object.prototype.toString.call(json).slice(8,-1) !== 'Object') 
        return false
        
     catch (e) 
        return false
    
    return true

然后我就能做到这一点:

expect(isJSON(body)).toBe(true)

【讨论】:

解析后的 Json 也可以包含一个数组。

以上是关于开玩笑;如何在字符串上测试 JSON.parse 会成功的主要内容,如果未能解决你的问题,请参考以下文章

如何正确声明一个json字符串?

如何解决冲突:使用开玩笑快照测试时“在源上删除,在目标上修改”?

开玩笑 - 如何测试组件是不是不存在?

如何将单引号 (') 捕获到 JSON.parse 的字符串中?

JSON.parse(JSON.stringify(e)) 将对象转换为字符串

请教jsonJSON.parse中双引号如何解决