MSTest 单元测试断言特定的异常消息
MSTest Unit Test asserting specific exception messages
我正在为非常小的项目编写我的第一个单元测试。这里的预期结果和结果都 return 一个 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)>.
首先,不要使用[ExpectedException]
。结果证明这是一种不好的做法,因为异常可能发生在任何地方。并且由于您使用 Assert.ThrowsException
,它不会进一步抛出异常,所以您的测试无论如何都会失败。
其次,我对 MSTest 不是很了解,但如果没有使用默认消息抛出异常,它似乎会失败。但是如果你不能在Assert.ThrowsException
中指定预期的错误信息,那么你可以实现自己的断言方法:
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
等方法,但你明白了。
看看这个;
var expectedExcetpion = new ArgumentNullException();
// Act & Assert
var result = Assert.ThrowsException<ArgumentNullException>(() => generateFile.InsertFileBeginning(parameter));
Assert.AreEqual(expectedExcetpion, result);
expectedException 是一个 ArgumentNullException
类型的对象,result 也是一个 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));
我正在为非常小的项目编写我的第一个单元测试。这里的预期结果和结果都 return 一个 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)>.
首先,不要使用[ExpectedException]
。结果证明这是一种不好的做法,因为异常可能发生在任何地方。并且由于您使用 Assert.ThrowsException
,它不会进一步抛出异常,所以您的测试无论如何都会失败。
其次,我对 MSTest 不是很了解,但如果没有使用默认消息抛出异常,它似乎会失败。但是如果你不能在Assert.ThrowsException
中指定预期的错误信息,那么你可以实现自己的断言方法:
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
等方法,但你明白了。
看看这个;
var expectedExcetpion = new ArgumentNullException();
// Act & Assert
var result = Assert.ThrowsException<ArgumentNullException>(() => generateFile.InsertFileBeginning(parameter));
Assert.AreEqual(expectedExcetpion, result);
expectedException 是一个 ArgumentNullException
类型的对象,result 也是一个 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));