Reputation: 3654
I really want to categorise some xunit tests as integration tests - but this:
[Fact]
[Trait("integration", "whatever")]
It is not ok with me. What I want to say is
[FactIntegration]
But I can't figure out a way to define a custom attribute that is like two attributes. Is there a way of doing this?
Upvotes: 1
Views: 65
Reputation: 37470
It is actually pretty simple.
If you want to extend some class' functionality, you are very likely to inherit from it.
TraitAttribute
is sealed, so it can't be inherited, so we can always go and see what the class does and try to replicate with custom code (not perfect, when the code is complex, but let's see).
Code for FactAttribute
[XunitTestCaseDiscoverer("Xunit.Sdk.FactDiscoverer", "xunit.execution.{Platform}")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class FactAttribute : Attribute
{
public virtual string DisplayName { get; set; }
public virtual string Skip { get; set; }
public virtual int Timeout { get; set; }
}
Code for TraitAttribute
[TraitDiscoverer("Xunit.Sdk.TraitDiscoverer", "xunit.core")]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
public sealed class TraitAttribute : Attribute, ITraitAttribute
{
public TraitAttribute(string name, string value) { }
}
As we can see, there are not much code going on in those classes.
In order to "inherit" TraitAttribute
functionalities, it's enough to inherit ITraitAttribute
interface, define appropeiate attributes and define constructor with two string params (name
and value
). Since we are inheriting interface for TraitAttribute
, we are (luckily!) free to just inherit FactAttribute
, since it is not sealed, and be done with our new attribute for tests:
[XunitTestCaseDiscoverer("Xunit.Sdk.FactDiscoverer", "xunit.execution.{Platform}")]
[TraitDiscoverer("Xunit.Sdk.TraitDiscoverer", "xunit.core")]
public class FactTraitAttribute(string name, string value) : FactAttribute, ITraitAttribute
{
}
Then you can have your specific attributes, such as FactIntegration
:
public class FactIntegrationAttribute : FactTraitAttribute
{
public FactIntegrationAttribute() : base("integration", "whatever") { }
}
Upvotes: 2