50

语境

在 XUnit github 中我发现了这个:Add Assert.Equal(expected, actual, message) 重载 #350 (所以开发人员要求不存在的重载见下文)

引用答案:

我们相信自我记录的代码;这包括你的断言。

(所以 XUnit 团队拒绝了它)

好,我知道了。我也相信自我记录的代码。我仍然找不到这个用例:

样本

// 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 中实现描述性断言消息?

4

3 回答 3

34

使用链接中提供的建议。就像流利的断言一样,或者创建自己的断言来包装Assert.True or Assert.False它们的消息重载。后面提到了

引用

您可以向 Assert.True 和 .False 提供消息。如果你根本无法没有消息(并拒绝使用不同的断言),你总是可以回退到:

Assert.True(number == 2, "This is my message");

引用:

如果你真的想要消息,你可以在你的测试项目中添加Fluent Assertions或者 xbehave 并使用它们的语法。如果 Fluent Assertions 遇到它的存在,它甚至会抛出 xunit.net 异常。

于 2017-02-13T13:06:17.073 回答
17

我遇到了同样的问题。我有一个测试,它从两个 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);
        }
    }
}

然后我可以做同样的断言:

AssertX.Equal(HttpStatusCode.OK, response1.StatusCode, $"Fetching {Uri1}");
AssertX.Equal(HttpStatusCode.OK, response2.StatusCode, $"Fetching {Uri2}");

并且错误日志给出了实际的、预期的,并在我的信息前面加上了哪个 webapi 是罪魁祸首。

我意识到我回答迟了,但认为这可能有助于其他人寻找实用的解决方案,而这些解决方案没有时间安装/学习另一个测试框架,只是为了从测试失败中获取有用的信息。

于 2018-10-24T16:17:19.503 回答
8

对于我的目的,使用try/catch就足够了:

try
{
    Assert.Equal(expectedErrorCount, result.Count);
}
catch (EqualException ex)
{
    throw new XunitException($"{testMsg}\n{ex}");
}
于 2021-04-22T06:32:13.937 回答