Skip to content

Instantly share code, notes, and snippets.

@drunkcod
Last active December 10, 2015 20:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drunkcod/4488313 to your computer and use it in GitHub Desktop.
Save drunkcod/4488313 to your computer and use it in GitHub Desktop.
a rough but workable way to "inject" contract tests into a NUnit fixture
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace NUnitBehavesLike
{
public interface IThingamabob
{
void Frooble();
bool IsFroobled { get; }
}
public class ThingamabobContract
{
public IThingamabob TheThingy;
public void is_froobled_after_a_frooble() {
TheThingy.Frooble();
Assert.That(TheThingy.IsFroobled);
}
}
public class SatisfiesAttribute : TestCaseSourceAttribute
{
class ContractSource<T>
{
public IEnumerable<ITestCaseData> GetContract()
{
return typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.DeclaringType != typeof(object) && x.ReturnType == typeof(void) && x.GetParameters().Length == 0)
.Select(x => new TestCaseData(new Action<T>(thingy => x.Invoke(thingy, null))).SetName(x.Name));
}
}
public SatisfiesAttribute(Type contractType) : base(typeof(ContractSource<>).MakeGenericType(contractType), "GetContract") { }
}
[TestFixture]
public class MyWidgetTests
{
class MyWidget : IThingamabob
{
public void Frooble() { }
public bool IsFroobled {
get { return false; }
}
}
/* many important facts about my widget omitted for brevity */
[Satisfies(typeof(ThingamabobContract))]
public void BehavesLikeAThingamabob(Action<ThingamabobContract> check) { check(new ThingamabobContract { TheThingy = MyThingy }); }
MyWidget MyThingy;
[SetUp]
public void CreateAWidget() {
MyThingy = new MyWidget();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment