C# 如何实现XUnit描述性断言消息?
上下文 在XUnitGithub中,我发现了这样一个问题:(因此,开发人员要求提供一个不存在的重载,请参见下文) 引述答案: 我们信奉自我记录代码;这包括你的主张 (因此XUnit团队拒绝了它) 好的,我知道了。我也相信自我记录代码。我还是不知道 此用例: 样本C# 如何实现XUnit描述性断言消息?,c#,unit-testing,xunit,assertions,xunit2,C#,Unit Testing,Xunit,Assertions,Xunit2,上下文 在XUnitGithub中,我发现了这样一个问题:(因此,开发人员要求提供一个不存在的重载,请参见下文) 引述答案: 我们信奉自我记录代码;这包括你的主张 (因此XUnit团队拒绝了它) 好的,我知道了。我也相信自我记录代码。我还是不知道 此用例: 样本 // Arrange // Create some external soap service client and its wrapper classes // Act // client.SomeMethod(); // Ass
// Arrange
// Create some external soap service client and its wrapper classes
// Act
// client.SomeMethod();
// Assert
// Sorry, soap service's interface, behaviour and design is *given*
// So I have to check if there is no Error, and
// conveniently if there is, then I would like to see it in the assertion message
Assert.Equal(0, client.ErrorMessage.Length); // Means no error
// I would like to have the same result what would be the following *N*U*n*i*t* assert:
// Assert.AreEqual(0, client.ErrorMessage.Length, client.ErrorMessage); // Means no error
问题
在这种情况下,如何在XUnit中实现描述性断言消息,而XUnit中仍然没有此类重载?使用链接中提供的建议。喜欢或创建自己的断言,该断言封装了消息重载留下的
Assert.True或Assert.False
。
它被进一步提到
您可以提供断言.True和.False的消息。如果你只是
没有信息就无法生活(拒绝使用不同的
断言),您可以始终返回到:
Assert.True(number == 2, "This is my message");
如果你真的想要留言,你可以添加或者
您的测试项目,并使用它们的语法。
流畅的断言甚至会在遇到xunit.net异常时抛出异常
我也有同样的问题。我有一个测试,它从两个web api中提取数据,然后比较和断言有关内容的各种内容。我开始使用标准的XUnit断言,如:
Assert.Equal(HttpStatusCode.OK, response1.StatusCode);
Assert.Equal(HttpStatusCode.OK, response2.StatusCode);
但是,虽然这提供了一条有用的消息,即404已返回,但从构建/CI服务器上的日志中不清楚是哪个服务导致了错误消息
最后,我添加了自己的断言以提供上下文:
public class MyEqualException : Xunit.Sdk.EqualException
{
public MyEqualException(object expected, object actual, string userMessage)
: base(expected, actual)
{
UserMessage = userMessage;
}
public override string Message => UserMessage + "\n" + base.Message;
}
public static class AssertX
{
/// <summary>
/// Verifies that two objects are equal, using a default comparer.
/// </summary>
/// <typeparam name="T">The type of the objects to be compared</typeparam>
/// <param name="expected">The expected value</param>
/// <param name="actual">The value to be compared against</param>
/// <param name="userMessage">Message to show in the error</param>
/// <exception cref="MyEqualException">Thrown when the objects are not equal</exception>
public static void Equal<T>(T expected, T actual, string userMessage)
{
bool areEqual;
if (expected == null || actual == null)
{
// If either null, equal only if both null
areEqual = (expected == null && actual == null);
}
else
{
// expected is not null - so safe to call .Equals()
areEqual = expected.Equals(actual);
}
if (!areEqual)
{
throw new MyEqualException(expected, actual, userMessage);
}
}
}
错误日志给出了我的消息的实际、预期和前置信息,其中webapi是罪魁祸首
我意识到我回答得太晚了,但我想这可能会帮助其他人寻找一个实用的解决方案,而他们没有时间安装/学习另一个测试框架,只是为了从测试失败中获取有用的信息。使用try/catch就足以满足我的目的:
try
{
Assert.Equal(expectedErrorCount, result.Count);
}
catch (EqualException ex)
{
throw new XunitException($"{testMsg}\n{ex}");
}
我不清楚问题是什么。为什么不只是使用
Assert.AreEqual(0,client.ErrorMessage.Length,client.ErrorMessage)代码>正如您在评论中指出的那样?XUnit中没有这种重载。那是一个修女的电话。请看最开始的一句话:一个开发人员要求这样一个重载,XUnit团队拒绝了,因为引用了“我们相信自文档代码;这包括您的断言”@g.pickardou,为什么不使用链接中提供的建议呢。类似于流畅的断言,或者创建自己的断言来包装消息重载留下的Assert.True或Assert.False
。下面提到了您可以提供断言.True和.False的消息。如果没有消息您就无法生活(并且拒绝使用不同的断言),那么您可以始终使用:Assert.True(number==2,“这是我的消息”)代码>@Nikosi:因为我没有得到那个:-)。这是一个答案,但是我仍然没有找到/得到你所指的流利样本。它是。。。让我们说“有趣”,XUnit维护人员锁定了您引用的票证,以确保他们不必再听到对此功能的投票(在说他们已经下定决心之后)。情况很清楚:失败时发出测试状态。代码显然可以是自文档化的,并且仍然可以从输出中获益,因为输出不必按照XUnit假设进行硬编码Assert.True(“所有输出必须是”==“硬编码”)
失败。我刚开始转换库,本来可以解决这个缺点的;但不是那种态度。这是一个答案,但是我仍然没有找到/得到你在评论中提到的流利的样本。这需要时间,但最终我得到了它。(这是我必须选择并立即使用的无数个单元测试框架…)返回到Assert.True(number==2,“这是我的消息”)
会产生一个更模糊的消息,隐藏比较的实际值:“这是我的消息预期值:True actual:False
”,所以这不是一个真正的选项(当然,我不是在抱怨你@Nkosi,只是想应该指出:)@TabsNotSpaces,而你的建议确实改善了一点,您仍然会收到一条较长的消息,其中包含两组预期值/实际值对:“这是我的消息预期值:2实际值:1预期值:True实际值:False
”。尽管如此,还是感谢您的建议:)尊重Xunit,真的,但不管他们多么自以为是,IMHO自文档化代码
与我们的CI/CD管道日志上的单元测试输出无关……:)这与其说是解决方案,还不如说是替代方案。通过使用流畅的验证(不管怎么说,这很糟糕),您在错误中丢失了所有良好的预期/实际提示。自定义Equal方法抛出EqualException而不是扩展的MyEqualException。我开始怀疑我选择xUnit而不是MSTest是否做得好。后者提供了更好的断言选项。有什么想法吗?
try
{
Assert.Equal(expectedErrorCount, result.Count);
}
catch (EqualException ex)
{
throw new XunitException($"{testMsg}\n{ex}");
}