Skip to content

Instantly share code, notes, and snippets.

@zvirja
Last active May 30, 2019 22:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zvirja/9366f23e28dd88e637d32bb52c025542 to your computer and use it in GitHub Desktop.
Save zvirja/9366f23e28dd88e637d32bb52c025542 to your computer and use it in GitHub Desktop.
AutoDataAttribute implementation which allows to easily apply test-specific customization
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using AutoFixture;
using AutoFixture.Xunit2;
using Xunit;
using Xunit.Sdk;
namespace CustomMyDataAttributesDemo
{
/* DECLARATIONS */
[DataDiscoverer("AutoFixture.Xunit2.NoPreDiscoveryDataDiscoverer", "AutoFixture.Xunit2")]
public class MyAutoDataAttribute : DataAttribute
{
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
var customizations = testMethod.GetCustomAttributes<CustomizeFixtureAttribute>()
.Select(attr => Activator.CreateInstance(attr.Type))
.Cast<ICustomization>();
return new CustomizedAutoData(customizations).GetData(testMethod);
}
private class CustomizedAutoData : AutoDataAttribute
{
public CustomizedAutoData(IEnumerable<ICustomization> customizations)
: base(() =>
{
var fixture = new Fixture();
// APPLY COMMON CUSTOMIZATIONS HERE
foreach (var customization in customizations)
{
fixture.Customize(customization);
}
return fixture;
})
{
}
}
}
public class InlineMyAutoDataAttribute : InlineAutoDataAttribute
{
public InlineMyAutoDataAttribute(params object[] values) : base(new MyAutoDataAttribute(), values)
{
}
}
[AttributeUsage(AttributeTargets.Method)]
public class CustomizeFixtureAttribute : Attribute
{
public Type Type { get; }
public CustomizeFixtureAttribute(Type type)
{
if(!typeof(ICustomization).IsAssignableFrom(type))
throw new ArgumentException("Type should be of ICustomization type.", nameof(type));
Type = type;
}
}
/******************* DEMO *******************/
public class DemoTests
{
[Theory]
[MyAutoData]
[CustomizeFixture(typeof(FortyTwoCustomization))]
public void AutoDataDemo(int number)
{
Assert.Equal(42, number);
}
[Theory]
[CustomizeFixture(typeof(FortyTwoCustomization))]
[InlineMyAutoData(100500)]
public void InlineAutoDataDemo(int staticNumber, int generatedNumber)
{
Assert.Equal(100500, staticNumber);
Assert.Equal(42, generatedNumber);
}
}
public class FortyTwoCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Inject(42);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment