由于非常具体的原因(如下所述),我尝试在执行单元测试后更改测试结果。 我尝试了以下代码:
[TestClass]
public class UnitTest1
{
public TestContext TestContext { get; set; }
[TestMethod]
public void TestMethod1()
{
Assert.Fail();
}
[TestCleanup]
public void Cleanup()
{
TestContext.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First((fieldInfo) => fieldInfo.Name.ToLowerInvariant().Contains("outcome"))
.SetValue(TestContext, UnitTestOutcome.Inconclusive);
}
}
和其他基于反射的变体。当我在执行TestCleanup方法后检查TestContext对象时,属性CurrentTestOutcome被正确设置为Inconclusive,但在此之后,测试仍然失败。
你有什么想法吗?我完全被困在这里......
由于
理由: 这些不是真实的"单元测试,但更多"端到端"试验。如果某些外部依赖失败(我知道如何检测它),并且测试失败,我想覆盖其结果以减少错误否定的数量。
答案 0 :(得分:1)
可能会迟到,但我设法为此找到了解决方案。
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.Common;
using System;
using System.Linq;
using System.Reflection;
namespace ServiceTests
{
[TestClass]
public class Test
{
public TestContext TestContext { get; set; }
[TestCleanup()]
public void MyTestCleanup()
{
if (TestContext.CurrentTestOutcome == UnitTestOutcome.Failed)
{
Type classType = this.GetType(TestContext.FullyQualifiedTestClassName);
if (classType != null)
{
object instance = Activator.CreateInstance(classType);
MethodInfo method = classType.GetMethod(TestContext.TestName);
try
{
method.Invoke(instance, null);
// if the above call does not throw exception it passes for sure,
// so changing the previous status and message is needed to be done.
FieldInfo resultField = TestContext.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.Name.Contains("m_currentResult")).First();
object currentTestResult = resultField.GetValue(TestContext);
FieldInfo outcomeProperty = currentTestResult.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.Name.Equals("m_outcome")).First();
outcomeProperty.SetValue(currentTestResult, TestOutcome.Passed);
FieldInfo errorInfoProperty = currentTestResult.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.Name.Equals("m_errorInfo")).First();
object errorInfoValue = errorInfoProperty.GetValue(currentTestResult);
FieldInfo messageProperty = errorInfoValue.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.Name.Equals("m_message")).First();
messageProperty.SetValue(errorInfoValue, "Passed.");
FieldInfo stackTraceProperty = errorInfoValue.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.Name.Equals("m_stackTrace")).First();
stackTraceProperty.SetValue(errorInfoValue, null);
}
catch
{
}
}
}
}
private static int i = 0;
[TestMethod]
public void TMethod()
{
i++;
if (i == 1)
Assert.Fail("Failed");
}
}
}