Nam*_*kwl 11 c# json nunit .net-core system.text.json
我正在将 .NET Framework 4.5 项目转换为 .NET Core 3.1。我的测试过去使用 Newtonsoft.Json 来检查 json 是否有效,现在我想使用内置的 System.Text.Json 来实现相同的功能。看起来
JsonElement values = JsonDocument.Parse(json).RootElement;
Run Code Online (Sandbox Code Playgroud)
throws System.Text.Json.JsonReaderException,但我无法捕获它,因为指向此异常会导致错误
命名空间“System.Text.Json”中不存在类型或命名空间名称“JsonReaderException”(您是否缺少程序集引用?)
我只是想了解如何可能抛出实际上似乎不存在的东西。
更新#1:堆栈跟踪:
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
at System.Text.Json.Utf8JsonReader.Read()
at System.Text.Json.JsonDocument.Parse(ReadOnlySpan`1 utf8JsonSpan, Utf8JsonReader reader, MetadataDb& database, StackRowStack& stack)
at System.Text.Json.JsonDocument.Parse(ReadOnlyMemory`1 utf8Json, JsonReaderOptions readerOptions, Byte[] extraRentedBytes)
at System.Text.Json.JsonDocument.Parse(ReadOnlyMemory`1 json, JsonDocumentOptions options)
at System.Text.Json.JsonDocument.Parse(String json, JsonDocumentOptions options)
at Anonymized..ctor(String json) in Anonymized.cs:line 182
at Anonymized.<>c__DisplayClass12_0.<TestCreateLogEntryFromJson_IllegalValues>b__0() in Anonymized.cs:line 206
at NUnit.Framework.Assert.Throws(IResolveConstraint expression, TestDelegate code, String message, Object[] args)
Run Code Online (Sandbox Code Playgroud)
更新#2:我去看看是否有一些我遗漏的东西。我发现 System.Text.Json 作为 nuget(尽管它已经可以访问,但我在测试文件中成功使用了 System.Text.JsonSerializer)。我添加了它,现在我遇到了实际问题:由于其保护级别,它无法访问。
using System.Text.Json;
namespace System.Text.Json
{
internal sealed class JsonReaderException : JsonException
{
public JsonReaderException(string message, long lineNumber, long bytePositionInLine);
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这并不能直接解决问题,我如何才能抓住这个问题Assert.Throws<System.Text.Json.JsonReaderException>?
System.Text.Json.JsonReaderException目前的事实internal表明,微软可能随时修改或删除该类型,并且用户不System.Text.Json应该依赖该类作为 public 的子类继续存在JsonException。事实上,文档Utf8JsonReader仅说明
当
Utf8JsonReader遇到无效的 JSON 时,它会抛出一个JsonException带有基本错误信息的错误信息,例如行号和行上的字节位置。
以及状态的代码注释JsonReaderException:
Run Code Online (Sandbox Code Playgroud)// This class exists because the serializer needs to catch reader-originated exceptions in order to throw JsonException which has Path information.
相反,断言抛出的异常是JsonException通过使用Is.InstanceOf<JsonException>()
Assert.Throws(Is.InstanceOf<JsonException>(), () => JsonDocument.Parse(json).Dispose());
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因您必须断言抛出的特定异常类型,您可以利用Assert.Throws()返回抛出的异常的事实来检查异常的完整类型名称:
Assert.AreEqual("System.Text.Json.JsonReaderException",
Assert.Throws(Is.InstanceOf<JsonException>(), () => JsonDocument.Parse(json).Dispose()).GetType().FullName);
Run Code Online (Sandbox Code Playgroud)
或者您可以使用 NUnit 的自定义约束机制并引入FullTypeNameConstraint如下所示:
using NUnit.Framework;
using NUnit.Framework.Constraints;
public class FullTypeNameConstraint : Constraint
{
readonly string expectedFullTypeName;
public FullTypeNameConstraint(string expectedFullTypeName) : base(expectedFullTypeName) => this.expectedFullTypeName = expectedFullTypeName;
public override string DisplayName => "FullTypeNameOf";
public override ConstraintResult ApplyTo<TActual>(TActual actual)
{
var actualTypeName = actual?.GetType().FullName;
return new ConstraintResult(this, actualTypeName, actualTypeName == expectedFullTypeName);
}
}
public class Is : NUnit.Framework.Is
{
public static FullTypeNameConstraint FullTypeNameOf(string expectedFullTypeName) => new FullTypeNameConstraint(expectedFullTypeName);
}
public static class CustomConstraintExtensions
{
public static FullTypeNameConstraint FullTypeNameOf(this ConstraintExpression expression, string expectedFullTypeName)
{
var constraint = new FullTypeNameConstraint(expectedFullTypeName);
expression.Append(constraint);
return constraint;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你将能够执行以下操作:
Assert.Throws(Is.FullTypeNameOf("System.Text.Json.JsonReaderException"), () => JsonDocument.Parse(json).Dispose());
Run Code Online (Sandbox Code Playgroud)
但老实说我不会推荐它。
顺便说一句,JsonDocument它是一次性的,实际上需要进行处置以释放池内存以供重用。
演示小提琴在这里: https: //dotnetfiddle.net/0dLxeO。
| 归档时间: |
|
| 查看次数: |
6332 次 |
| 最近记录: |