How to implement XUnit descriptive Assert message?

后端 未结 2 1168
迷失自我
迷失自我 2021-02-05 01:45

Context

in XUnit github I found this: Add Assert.Equal(expected, actual, message) overload #350 (so a developer ask for a non existing overload see

2条回答
  •  后悔当初
    2021-02-05 02:03

    I was having the same issue. I've a test that pulls data from two web api's and then compares and asserts various things about the content. I started using standard XUnit assertions like:

    Assert.Equal(HttpStatusCode.OK, response1.StatusCode);
    Assert.Equal(HttpStatusCode.OK, response2.StatusCode);
    

    But whilst this gives a useful message that a 404 has been returned, it not clear from the logs on our build/CI server which service caused the error message.

    I ended up adding my own assertion to give context:

    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
    {
        /// 
        /// Verifies that two objects are equal, using a default comparer.
        /// 
        /// The type of the objects to be compared
        /// The expected value
        /// The value to be compared against
        /// Message to show in the error
        /// Thrown when the objects are not equal
        public static void Equal(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);
            }
        }
    }
    

    Then I can do the same assertions as:

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

    and the error log gives the actual,expected and prepends my message about which webapi was the culprit.

    I realise I'm late to answer, but figured this might help others searching for a practical solution that don't have time to install/learn yet another test framework just to get useful information out of test failures.

提交回复
热议问题