Files
Dapper/Dapper.Tests/XunitSkippable.cs
Nick Craver d28f2cf4bf Skip MySQL tests if the server isn't running.
This is the "approved" xUnit pattern, via:
https://github.com/xunit/samples.xunit/tree/master/DynamicSkipExample
It's also the only way I can make the damn skipping work...but at least
it's it's one-time code to make any server set relatively easily
skippable.
2015-11-26 07:36:28 -05:00

99 lines
3.5 KiB
C#

using System;
#if XUNIT2 // Not in .Net 4.0 (xUnit v1)...
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
using Xunit.Sdk;
#endif
namespace Dapper.Tests
{
public class SkipTestException : Exception
{
public SkipTestException(string reason) : base(reason) { }
}
#if XUNIT2
// Most of the below is a direct copy & port from the wonderful examples by Brad Wilson at
// https://github.com/xunit/samples.xunit/tree/master/DynamicSkipExample
public class SkippableFactDiscoverer : IXunitTestCaseDiscoverer
{
readonly IMessageSink _diagnosticMessageSink;
public SkippableFactDiscoverer(IMessageSink diagnosticMessageSink)
{
_diagnosticMessageSink = diagnosticMessageSink;
}
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
yield return new SkippableFactTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod);
}
}
public class SkippableFactTestCase : XunitTestCase
{
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public SkippableFactTestCase() { }
public SkippableFactTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, ITestMethod testMethod, object[] testMethodArguments = null)
: base(diagnosticMessageSink, defaultMethodDisplay, testMethod, testMethodArguments)
{ }
public override async Task<RunSummary> RunAsync(
IMessageSink diagnosticMessageSink,
IMessageBus messageBus,
object[] constructorArguments,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
{
var skipMessageBus = new SkippableFactMessageBus(messageBus);
var result = await base.RunAsync(
diagnosticMessageSink,
skipMessageBus,
constructorArguments,
aggregator,
cancellationTokenSource);
if (skipMessageBus.DynamicallySkippedTestCount > 0)
{
result.Failed -= skipMessageBus.DynamicallySkippedTestCount;
result.Skipped += skipMessageBus.DynamicallySkippedTestCount;
}
return result;
}
}
public class SkippableFactMessageBus : IMessageBus
{
readonly IMessageBus _innerBus;
public SkippableFactMessageBus(IMessageBus innerBus)
{
_innerBus = innerBus;
}
public int DynamicallySkippedTestCount { get; private set; }
public void Dispose() { }
public bool QueueMessage(IMessageSinkMessage message)
{
var testFailed = message as ITestFailed;
if (testFailed != null)
{
var exceptionType = testFailed.ExceptionTypes.FirstOrDefault();
if (exceptionType == typeof(SkipTestException).FullName)
{
DynamicallySkippedTestCount++;
return _innerBus.QueueMessage(new TestSkipped(testFailed.Test, testFailed.Messages.FirstOrDefault()));
}
}
return _innerBus.QueueMessage(message);
}
}
#endif
}