Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃悰 Enum data type is not applied when a member has both [StringLength] and [EnumDataType] annotations #1409

Open
2 tasks done
cervengoc opened this issue Oct 11, 2023 · 4 comments
Labels
bug data annotations An issue related to data annotations triage Something that's being investigated

Comments

@cervengoc
Copy link

cervengoc commented Oct 11, 2023

Describe the Bug

In our EF Core data layer, in most cases enums are mapped as strings. So we have several classes where a member has both [StringLength] and [EnumDataType] attributes. When using AutoFixture to create an instance of such a class, the latter attribute is disregarded.

Scenario

public enum TestEnum {
    One = 1,
    Two,
    Three
}

public class Test {
    [StringLength(64)]
    [EnumDataType(typeof(TestEnum))]
    public string EnumAsString { get; set; }
}

Expected Behavior

I'd expect that the [EnumDataType] attribute has a stronger precedence as it's more strict than a string length.

Tasks

  • Updated all AutoFixture and related libraries
  • Confirmed in support forums if behavior is expected

More Information

As I digged into the source code I saw that EnumDataTypeAttributeRelay is after StringLengthAttributeRelay in the Fixture constructor. Seems to me that it should be before that, and it would instantly solve the issue.

Thanks!

EDIT: I'm aware of built-in options to map enums as strings in EF Core. It's a rather old codebase, and right now we're not able to do such a refactor.

@cervengoc cervengoc added the bug label Oct 11, 2023
@cervengoc cervengoc changed the title 馃悰 Enum data type is not applied when a member has both [StringLength] and [EnumDataType] annotations Oct 11, 2023
@aivascu aivascu added the triage Something that's being investigated label Dec 4, 2023
@aivascu aivascu changed the title Enum data type is not applied when a member has both [StringLength] and [EnumDataType] annotations 馃悰 Enum data type is not applied when a member has both [StringLength] and [EnumDataType] annotations Dec 4, 2023
@aivascu aivascu added the data annotations An issue related to data annotations label Dec 5, 2023
@cervengoc
Copy link
Author

Hi @aivascu ,
Is there any update on this one? The need for some kind of a fix has just come up again.
Best regards

@aivascu
Copy link
Member

aivascu commented Apr 23, 2024

Hi @cervengoc ,
I'll have a look today if I can find a workaround. Even if fixed it will go into the next major version which is currently in preview.

@aivascu
Copy link
Member

aivascu commented Apr 23, 2024

@cervengoc so, as a workaround for prioritizing the data annotations attributes differently, or adding support for more attributes, it's possible to insert a new customization node at the front of the Fixture.Customizations collection.
You should be able to encapsulate this behavior into a ICustomization implementation and reuse it across the codebase.

var builder = new CompositeSpecimenBuilder(
        new EnumDataTypeAttributeRelay(),
        new EnumRangedRequestRelay(),
        new RegularExpressionAttributeRelay(),
        new TimeSpanRangedRequestRelay(),
        new RangeAttributeRelay(),
        new NumericRangedRequestRelay(),
        new MinAndMaxLengthAttributeRelay(),
        new StringLengthAttributeRelay());
fixture.Customizations.Insert(0, builder);

I'll postpone a permanent fix until I decide how to address this request in combination with #1091 and #1348.

Full code
public class UnitTests
{
  [Fact]
  public void Foo()
  {
      var fixture = new Fixture().Customize(new CustomDataAnnotationsCustomization());

      var actual = fixture.Create<TestType>();

      actual.EnumAsString.Should().BeOneOf("One", "Two", "Three");
      actual.RegexString.Length.Should().Be(15);
  }
}

public enum TestEnum
{
  One = 1,
  Two,
  Three,
}

public class TestType
{
  [StringLength(64)]
  [EnumDataType(typeof(TestEnum))]
  public string EnumAsString { get; set; }

  [StringLength(12)]
  [RegularExpression("^[A-Z]{15}")]
  public string RegexString { get; set; }
}

public class CustomDataAnnotationsCustomization : ICustomization
{
  public void Customize(IFixture fixture)
  {
      var builder = new CompositeSpecimenBuilder(
          new EnumDataTypeAttributeRelay(),
          new EnumRangedRequestRelay(),
          new RegularExpressionAttributeRelay(),
          new RangeAttributeRelay(),
          new NumericRangedRequestRelay(),
          new TimeSpanRangedRequestRelay(),
          new StringLengthAttributeRelay(),
          new MinAndMaxLengthAttributeRelay());
      fixture.Customizations.Insert(0, builder);
  }
}

@cervengoc
Copy link
Author

Thank you for the workaround suggestion, looks reasonable for now, especially as we already have a bunch of customizations around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug data annotations An issue related to data annotations triage Something that's being investigated
Projects
None yet
Development

No branches or pull requests

2 participants