0

I'm writing integrational test to my UserController. And currently testing User creation method using AutoFixture. CreateUser method accepts CreateUserDto

public class CreateUserDto : IMapWith<User>
    {
        public string Username { get; init; }
        public string Name { get; init; }
        public string Surname { get; init; }
        public DateTime BirthDay { get; init; }
        public UserTypeId UserTypeId { get; init; }
        public Guid CityId { get; init; }
        public string Email { get; init; }
        public string PhoneNumber { get; init; }
        public Guid OrientationId { get; init; }
        public Guid GenderId { get; init; }

        public void Mapping(Profile profile)
        {
            profile.CreateMap<CreateUserDto, User>();
        }
    }

And i want to set Email to have and email look and PhoneNumber to have only 11 digits. For email i tried this but it's not working it still generates guid instead of email:

var fixture = GetFixture();
            fixture.Customizations.Add(new MailAddressGenerator());
var userDto = fixture.Create<CreateUserDto>();

I don't even know how to customize number.

EDIT

I tried to create it with custom customization:

internal class EmailAndPhoneNumberCustomization : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Customize<CreateUserDto>(c => c
                .With(u => u.Email, "test@test.com")
                .With(u => u.PhoneNumber, "87777777777"));
        }
    }

And it's ignoring it. Code where i use it:

private async Task<IEnumerable<UserEntity>> GenerateUsers()
        {
            var fixture = GetFixture();

            var users = fixture.CreateMany<UserEntity>(3);

            return users;
        }

        private static Fixture GetFixture()
        {
            var fixture = new Fixture();
            fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList().ForEach(behavior => fixture.Behaviors.Remove(behavior));
            fixture.Behaviors.Add(new OmitOnRecursionBehavior());
            fixture.Customize(new EmailAndPhoneNumberCustomization());
            return fixture;
        }
  • https://stackoverflow.com/questions/36365147/autofixture-create-a-list-of-email-addresses – David Osborne Dec 19 '22 at 09:37
  • @DavidOsborne I updated my question. it's somehow not working with this method that i provided but works if i create Fixture and customize it in my test's – UntitledUserForEach Dec 19 '22 at 10:53
  • 1
    Try fixture.CreateMany(3) instead of fixture.CreateMany(3) – Yevhen Cherkes Dec 19 '22 at 11:26
  • @YevhenCherkes damn im blind lol. thanks, but is there any way to make that easier? i don't want to type every entity that validation for email and phoneNumber. how can i add it to general customization so that it will be common every entity that contains email and phoneNumber? – UntitledUserForEach Dec 19 '22 at 11:37
  • 2
    I think an `ISpecimenBuilder` is what you want: https://blog.ploeh.dk/2010/10/19/Convention-basedCustomizationswithAutoFixture/ – David Osborne Dec 19 '22 at 12:24

1 Answers1

0

As mentioned in the comments the generic type in CreateMany<>(3) is wrong, should be the customized type. As for making it easier, depending on your testing framework you can make use of data attributes and inject the values into your test method. To make data attribute creation easier, you can encapsulate the customization using the ICustomization interface.

The example below demonstrates how to encapsulate the customization into reusable classes and how to generate mail addresses and phone numbers.

/* recursion omitter customization */
public class OmitRecursionCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Behaviors.OfType<ThrowingRecursionBehavior>()
            .ToList().ForEach(behavior => fixture.Behaviors.Remove(behavior));
        fixture.Behaviors.Add(new OmitOnRecursionBehavior());
    }
}

/* your DTO customizations */
public class DtoCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customize<CreateUserDto>(c => c
                .With(u => u.Email, fixture.Create<MailAddress>().Address)
                .With(u => u.PhoneNumber, fixture.Create(
                    new RegularExpressionRequest("[1-9]{11}"),
                    new SpecimenContext(fixture))));
    }
}
/* The data attribute customization */
public class DomainDataAttribute : AutoDataAttribute
{
    public DomainDataAttribute()
        : base(() => new Fixture().Customize(
            new CompositeCustomization(
                new OmitRecursionCustomization(),
                new DtoCustomization())))
    {
    }
}
/* The test */
[Theory, DomainData]
public void Foo(List<CreateUserDto> users)
{
    Assert.Equal(3, users.Count);
    Assert.All(users, user => Assert.Matches(@"\@example\.(com|org|net)", user.Email));
    Assert.All(users, user => Assert.Matches("[1-9]{11}", user.PhoneNumber));
}
Andrei Ivascu
  • 1,172
  • 8
  • 17