【问题标题】:MSTest Unit Test asserting specific exception messagesMSTest 单元测试断言特定异常消息
【发布时间】:2020-04-28 08:42:13
【问题描述】:

我正在为非常小的项目编写我的第一个单元测试。这里预期的结果和结果都返回 ArgumentNullException 但测试仍然失败。知道为什么吗?

        [TestMethod]
        public void InsertFileBeginning_FilePathNull_ReturnArgumentNullException()
        {
            // Arrange
            var generateFile = new GenerateFile();
            string parameter = null; //pass FilePath Null

            var expectedExcetpion = new ArgumentNullException();

            // Act & Assert
            var result = Assert.ThrowsException<ArgumentNullException>(() => generateFile.InsertFileBeginning(parameter));
            Assert.AreEqual(expectedExcetpion, result);

        }

--------InsertFileBeginning 函数--------

public void InsertFileBeginning(string filePath)
        {
            try
            {
                using (var fs = new FileStream(filePath, FileMode.Create))
                {
                    Byte[] metadata = new UTF8Encoding(true).GetBytes("THis is a test content");
                    fs.Write(metadata, 0, metadata.Length);

                }
            }
            catch (Exception exception)
            {
                throw exception;
            }

        }

错误:

预期:System.ArgumentNullException:值不能为空。

实际:System.ArgumentNullException:路径不能为空。参数名称:路径

Message: Assert.AreEqual failed. Expected:<System.ArgumentNullException: Value cannot be null.>. Actual:<System.ArgumentNullException: Path cannot be null.
Parameter name: path
   at SmartTestSelecter.GenerateFile.InsertFileBeginning(String filePath) in C:\Users\CC\SmartTestSelecter\GenerateFile.cs:line 31
   at SmartTestSelecterUnitTests.GenerateFileTest.<>c__DisplayClass0_0.<InsertFileBeginning_FilePathNull_ReturnArgumentNullException>b__0() in C:\Users\CC\STSUnitTests\GenerateFileTest.cs:line 21
   at Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException[T](Action action, String message, Object[] parameters)>. 

【问题讨论】:

标签: c# unit-testing exception mstest argumentnullexception


【解决方案1】:

首先,不要使用[ExpectedException]。事实证明这是一种不好的做法,因为异常可能发生在任何地方。而且由于您使用Assert.ThrowsException,它不会进一步引发异常,因此您的测试无论如何都会失败。

其次,我对 MSTest 不是很了解,但如果默认消息未引发异常,它似乎会失败。但是如果你不能在Assert.ThrowsException中指定预期的错误信息,那么你可以实现你自己的assert方法:

public static void Throws<T>(Action action, string expectedMessageContent = null)
    where T : Exception
{
    try
    {
        action.Invoke();
    }
    catch (Exception e)
    {
        Assert.IsInstanceOf(typeof(T), e);
        Assert.IsTrue(expectedMessageContent == null
            || e.Message.Contains(expectedMessageContent), $"Expected message: {expectedMessageContent}{Environment.NewLine}Actual message:{e.Message}");
        return;
    }

    Assert.Fail("No exception was thrown");
}

免责声明:我不知道 MSTest 是否有 Assert.IsInstanceOf 等方法,但你明白这一点。

【讨论】:

    【解决方案2】:

    看看这个;

    var expectedExcetpion = new ArgumentNullException();
    // Act & Assert
    var result = Assert.ThrowsException<ArgumentNullException>(() => generateFile.InsertFileBeginning(parameter));
    Assert.AreEqual(expectedExcetpion, result);
    

    expectedException 是 ArgumentNullException 类型的对象,结果也是 ArgumentNullException 类型的对象 - 但是它们不是同一个对象!您有 2 个相同类型的实例。

    现在 AreEqual(..) 使用 .Equals 来自我可以在线收集的信息。

    我认为您在这里将 expectedException 的引用与 result 进行比较。他们当然不一样。你应该做的(如果我的假设是正确的)是检查结果是否属于同一类型,而不是使用AreEqual(..)

    看来您可以使用此方法: Assert.IsInstanceOfType https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.isinstanceoftype?view=mstest-net-1.2.0

    例如:

    Assert.IsInstanceOfType(result, typeof(ArgumentNullException));
    

    【讨论】:

    • 这正是问题所在。谢谢你。现在只有我明白我的编码出了什么问题。感谢大家的时间和帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2023-04-10
    • 2013-03-16
    • 2018-09-26
    • 2011-07-19
    • 1970-01-01
    相关资源
    最近更新 更多