gpt4 book ai didi

c# - MemberData 测试显示为一个测试而不是多个

转载 作者:IT王子 更新时间:2023-10-29 04:24:02 27 4
gpt4 key购买 nike

当您将 [Theory][InlineData] 一起使用时,它将为提供的每项内联数据创建一个测试。但是,如果您使用 [MemberData],它只会显示为一个测试。

有没有办法让 [MemberData] 测试显示为多个测试?

最佳答案

我花了很多时间试图在我的项目中解决这个问题。 This related Github discussion来自@NPadrutt 自己的帮助很大,但仍然令人困惑。

tl;dr 是这样的:[MemberInfo] 将报告单个组测试,除非为每个测试提供的对象可以通过实现 完全序列化和反序列化>IXunitSerializable.


背景

我自己的测试设置是这样的:

public static IEnumerable<object[]> GetClients()
{
yield return new object[] { new Impl.Client("clientType1") };
yield return new object[] { new Impl.Client("clientType2") };
}

[Theory]
[MemberData(nameof(GetClients))]
public void ClientTheory(Impl.Client testClient)
{
// ... test here
}

正如预期的那样,测试运行了两次,一次针对来自 [MemberData] 的每个对象。正如@NPadrutt 所经历的,只有一个项目出现在测试资源管理器中,而不是两个。这是因为提供的对象 Impl.Client 不能被 xUnit 支持的任何一个接口(interface)序列化(稍后详细介绍)。

就我而言,我不想将测试问题渗入到我的主要代码中。我以为我可以围绕我的真实类编写一个瘦代理,让 xUnit 运行器误以为它可以序列化它,但是在与它战斗的时间比我愿意承认的要长之后,我意识到我不理解的部分是:

The objects aren't just serialized during discovery to count permutations; each object is also deserialized at test run time as the test starts.

因此,您使用 [MemberData] 提供的任何对象都必须支持完整的往返(反)序列化。现在这对我来说似乎很明显,但是在我试图弄明白的时候找不到任何相关文档。


解决方案

  • 确保每个对象(以及它可能包含的任何非原始对象)都可以完全序列化和反序列化。实现 xUnit 的 IXunitSerializable 告诉 xUnit 它是一个可序列化的对象。

  • 如果像我的情况一样,您不想向主代码添加属性,一个解决方案是创建一个用于测试的可序列化的精简生成器类,它可以表示重新创建实际类所需的一切。这是上面的代码,在我让它工作之后:

测试客户端生成器

public class TestClientBuilder : IXunitSerializable
{
private string type;

// required for deserializer
public TestClientBuilder()
{
}

public TestClientBuilder(string type)
{
this.type = type;
}

public Impl.Client Build()
{
return new Impl.Client(type);
}

public void Deserialize(IXunitSerializationInfo info)
{
type = info.GetValue<string>("type");
}

public void Serialize(IXunitSerializationInfo info)
{
info.AddValue("type", type, typeof(string));
}

public override string ToString()
{
return $"Type = {type}";
}
}

测试

public static IEnumerable<object[]> GetClients()
{
yield return new object[] { new TestClientBuilder("clientType1") };
yield return new object[] { new TestClientBuilder("clientType2") };
}

[Theory]
[MemberData(nameof(GetClients))]
private void ClientTheory(TestClientBuilder clientBuilder)
{
var client = clientBuilder.Build();
// ... test here
}

有点烦人的是我不再注入(inject)目标对象,但这只是调用我的构建器的额外代码行。而且,我的测试通过了(并且出现了两次!),所以我没有提示。

关于c# - MemberData 测试显示为一个测试而不是多个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30574322/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com