运行此测试时:
[TestMethod]
[ExpectedException(typeof(SpecialException))]
public void Test1()
{
throw new NotImplementedException();
}
Visual Studio告诉我它失败的原因:
测试方法[...]。测试1投掷 异常System.NotImplementedException,但异常 [...]。期待SpecialException。例外 message:System.NotImplementedException:方法或操作是 没有实施。
但是当我尝试扩展ExpectedExceptionBaseAttribute
(期望SpecialException
中的错误代码)时:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
class ExpectedSpecialException : ExpectedExceptionBaseAttribute
{
protected override void Verify(Exception exception)
{
SpecialException se = exception as SpecialException;
if (se == null)
{
RethrowIfAssertException(exception);
throw new Exception("SpecialException was expected but test method threw another one");
}
}
}
并使用它:
[TestMethod]
[ExpectedSpecialException]
public void Test1()
{
throw new NotImplementedException();
}
VS产生了一条信息量不大的消息:
调用目标抛出了异常。
我在互联网上找到的扩展ExpectedExceptionBaseAttribute
的所有示例(1,2,3)都尝试提供有关抛出异常失败的更多信息,但没有结果。
我做错了吗?有没有办法提供有关此类失败测试的更多信息?
答案 0 :(得分:3)
我认为您在问题中引用的任何帖子都没有正确实现自定义的ExpectedException属性。我不是说它们不是有效的解决方案,我说它们解决了不同的问题。我认为你所经历的是一个不同的问题,这些问题都没有得到解决。
由于 null TestContext,您似乎没有收到完整的错误消息。
您可以通过查看ExpectedExceptionAttribute的实施来验证这一点。 您可以使用反射器,您可以看到它在内部使用TestContext。
如果你看一下 ExpectedExceptionBaseAttribute 的实现
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,
Inherited = true)]
public abstract class ExpectedExceptionBaseAttribute : Attribute
{
protected internal TestContext TestContext { get; internal set; }
TestContext在运行时设置内部,不能注入 ExpectedSpecialException 属性。 MSTest的 ExpectedExceptionAttribute 可以访问由测试运行器内部设置的 TestContext 。需要注意的是,由于MSTest缺乏可扩展性,我们无法真正根据需要访问和设置TestContext。
不确定这会有所帮助,但您可以使用像this这样的方法自定义异常和引发异常的位置。我认为这是一种更好的方法。
答案 1 :(得分:0)
为了它的价值,我通过仅将断言异常传递给基础RethrowIfAssertException
函数来解决这个问题:
protected override void Verify(Exception exception)
{
if (exception is UnitTestAssertException)
{
RethrowIfAssertException(exception);
}
try
{
Assert.IsInstanceOfType<SpecialException>(exception);
}
catch (AssertionFailedException ex)
{
RethrowIfAssertException(ex);
}
}
答案 2 :(得分:0)
经过我自己的研究以找到解决方案,我发现对于版本11(VS2012),它似乎是VSTestIntegration
dll中的错误。
Microsoft.VisualStudio.TestPlatform.MSTestFramework.TestMethodRunner.HandleMethodException
方法使用反射调用调用ExpectedExceptionBaseAttribute
以外的继承的ExpectedExceptionAttribute
类。根据{{3}},如果“被调用的方法或构造函数引发异常”,则返回TargetInvocationException
,真正的异常在InnerException
中。
不幸的是,HandleMethodException
不会通过显示来检查消息的内部异常
调用的目标已引发异常。
此问题已在版本14(VS2017)中修复,并且可能早于此版本,但我没有要对其进行验证。 dll位于
'C:\ Program Files(x86)\ Microsoft Visual Studio [version] \ Common7 \ IDE \ CommonExtensions \ Microsoft \ TestWindow \ Extensions \ Microsoft.VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll
感谢@ Jon-Skeet购买了MS documentation。