-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Use
AutoDomainData
attribute instead of directly mocking …
…with `NSubstitute` (#648) Add a custom `AutoDomainData` extension of [`AutoDataAttribute`](https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixture.xUnit2/AutoDataAttribute.cs), that uses [NSubstitute](https://nsubstitute.github.io) and allows for domain-specific [customizations](https://autofixture.github.io/docs/fixture-customization/). In order to apply a customization for all tests in a project, add a class implementing the `IAutoDataCustomization` interface. This customization is then applied to all tests using the `[AutoDomainData]` attribute. Additionally this attribute has a property `CustomizeWith` which can point to a class implementing the [`ICustomization`](https://autofixture.github.io/docs/fixture-customization/) interface and which is then applied to this test only.
- Loading branch information
Showing
6 changed files
with
132 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
Tests/Helpers/Testably.Abstractions.TestHelpers/AutoDomainDataAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
using AutoFixture; | ||
using AutoFixture.Xunit2; | ||
using AutoFixture.AutoNSubstitute; | ||
using System; | ||
using System.Linq; | ||
using System.Collections.Generic; | ||
|
||
namespace Testably.Abstractions.TestHelpers; | ||
|
||
/// <summary> | ||
/// Extension of <see cref="AutoDataAttribute"/> that uses applies domain-specific customizations. | ||
/// </summary> | ||
public class AutoDomainDataAttribute : AutoDataAttribute | ||
{ | ||
private Type? _customizeWith; | ||
private readonly FixtureFactory _fixtureFactory; | ||
|
||
/// <summary> | ||
/// Extension of <see cref="AutoDataAttribute"/> that uses applies domain-specific customizations. | ||
/// </summary> | ||
public AutoDomainDataAttribute() : this(new FixtureFactory()) | ||
{ | ||
} | ||
|
||
private AutoDomainDataAttribute(FixtureFactory fixtureFactory) | ||
: base(fixtureFactory.GetFixtureFactory) | ||
{ | ||
_fixtureFactory = fixtureFactory; | ||
} | ||
|
||
/// <summary> | ||
/// Adds an additional <see cref="ICustomization"/> that is applied for only this test. | ||
/// </summary> | ||
public Type? CustomizeWith | ||
{ | ||
get | ||
{ | ||
return _customizeWith; | ||
} | ||
set | ||
{ | ||
_customizeWith = value; | ||
_fixtureFactory.CustomizeWith(value); | ||
} | ||
} | ||
|
||
private sealed class FixtureFactory | ||
{ | ||
private ICustomization? _customizeWith; | ||
private static Lazy<ICustomization[]> _domainCustomisation { get; } = new(Initialize); | ||
|
||
public IFixture GetFixtureFactory() | ||
{ | ||
var fixture = new Fixture(); | ||
fixture.Customize(new AutoNSubstituteCustomization()); | ||
foreach (var domainCustomization in _domainCustomisation.Value) | ||
{ | ||
domainCustomization.Customize(fixture); | ||
} | ||
if (_customizeWith != null) | ||
{ | ||
fixture.Customize(_customizeWith); | ||
} | ||
return fixture; | ||
} | ||
|
||
public void CustomizeWith(Type? type) | ||
{ | ||
Type customizationInterface = typeof(ICustomization); | ||
if (type != null && | ||
customizationInterface.IsAssignableFrom(type)) | ||
{ | ||
try | ||
{ | ||
_customizeWith = (ICustomization?)Activator.CreateInstance(type); | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new InvalidOperationException( | ||
$"Could not instantiate customization with '{type.Name}'!", ex); | ||
} | ||
} | ||
} | ||
|
||
private static ICustomization[] Initialize() | ||
{ | ||
List<ICustomization> domainCustomizations = new(); | ||
Type autoDataCustomizationInterface = typeof(IAutoDataCustomization); | ||
foreach (Type type in AppDomain.CurrentDomain.GetAssemblies() | ||
.SelectMany(a => a.GetTypes()) | ||
.Where(x => x.IsClass) | ||
.Where(autoDataCustomizationInterface.IsAssignableFrom)) | ||
{ | ||
try | ||
{ | ||
IAutoDataCustomization? domainCustomization = (IAutoDataCustomization?)Activator.CreateInstance(type); | ||
if (domainCustomization != null) | ||
{ | ||
domainCustomizations.Add(domainCustomization); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new InvalidOperationException( | ||
$"Could not instantiate auto data customization '{type.Name}'!", ex); | ||
} | ||
} | ||
return domainCustomizations.ToArray(); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
Tests/Helpers/Testably.Abstractions.TestHelpers/IAutoDataCustomization.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using AutoFixture; | ||
|
||
namespace Testably.Abstractions.TestHelpers; | ||
|
||
/// <summary> | ||
/// Marks customizations of <see cref="IFixture"/> that should always be applied when using the <see cref="AutoDomainDataAttribute"/>. | ||
/// </summary> | ||
public interface IAutoDataCustomization : ICustomization | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters