问题
I have this property:
public SubjectStatus Status
{
get { return status; }
set
{
if (Enum.IsDefined(typeof(SubjectStatus), value))
{
status = value;
}
else
{
Debug.Fail("Error setting Subject.Status", "There is no SubjectStatus enum constant defined for that value.");
return;
}
}
}
and this unit test
[Test]
public void StatusProperty_StatusAssignedValueWithoutEnumDefinition_StatusUnchanged()
{
Subject subject = new TestSubjectImp("1");
// assigned by casting from an int to a defined value
subject.Status = (SubjectStatus)2;
Assert.AreEqual(SubjectStatus.Completed, subject.Status);
// assigned by casting from an int to an undefined value
subject.Status = (SubjectStatus)100;
// no change to previous value
Assert.AreEqual(SubjectStatus.Completed, subject.Status);
}
Is there a way I can prevent Debug.Fail displaying a message box when I run my tests, but allow it to show me one when I debug my application?
回答1:
The standard way I've always done this is to create a plugin for NUnit. The plugin simply unregisters the default trace listener and registers a replacement that throws an exception when Assert/Trace.Fail is triggered. I like this approach because tests will still fail if a assert trips, you don't get any message boxes popping up and you don't have to modify your production code.
Edit -- here's the plugin code in its entirety. You're on your own for building the actual plugin though -- check the NUnit site :)
[NUnitAddin]
public class NUnitAssertionHandler : IAddin
{
public bool Install(IExtensionHost host)
{
Debug.Listeners.Clear();
Debug.Listeners.Add(new AssertFailTraceListener());
return true;
}
private class AssertFailTraceListener : DefaultTraceListener
{
public override void Fail(string message, string detailMessage)
{
Assert.Fail("Assertion failure: " + message);
}
public override void Fail(string message)
{
Assert.Fail("Assertion failure: " + message);
}
}
}
回答2:
An alternative way that doesn't require changing your production code or writing a custom NUnit add-in, would be to replace the trace listeners in a setup fixture.
E.g. Add the following class inside the namespace your tests are in:
using System;
using System.Diagnostics;
using NUnit.Framework;
[SetUpFixture]
public class NUnitSetup
{
// Field to hold exisitng trace listeners so they can be restored after test are run.
private TraceListener[] originalListeners = null;
// A trace listener to use during testing.
private TraceListener nunitListener = new NUnitListener();
[SetUp]
public void SetUp()
{
// Replace existing listeners with listener for testing.
this.originalListeners = new TraceListener[Trace.Listeners.Count];
Trace.Listeners.CopyTo(this.originalListeners, 0);
Trace.Listeners.Clear();
Trace.Listeners.Add(this.nunitListener);
}
[TearDown]
public void TearDown()
{
// Restore original trace listeners.
Trace.Listeners.Remove(this.nunitListener);
Trace.Listeners.AddRange(this.originalListeners);
}
public class NUnitListener : DefaultTraceListener
{
public override void Fail(string message)
{
Console.WriteLine("Ignoring Debug.Fail(\"{0}\")", message);
}
public override void Fail(string message, string detailMessage)
{
Console.WriteLine("Ignoring Debug.Fail(\"{0},{1}\")", message, detailMessage);
}
}
}
回答3:
Instead of calling Debug.Assert directly, you could call a wrapper method that checks whether a debugger is attached before invoking Debug.Assert. (Presumably, it should throw an exception if there is no debugger attached so that your tests will fail.) e.g.:
[Conditional("DEBUG")]
public static void Assert(bool condition)
{
if (Debugger.IsAttached)
{
Debug.Assert(condition);
}
else
{
throw new SomeException();
}
}
来源:https://stackoverflow.com/questions/2662041/can-i-configure-nunit-so-that-debug-fail-doesnt-show-a-message-box-when-i-run-m