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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FromFactory does not work as intended #898

Closed
Ephasme opened this issue Oct 26, 2017 · 3 comments
Closed

FromFactory does not work as intended #898

Ephasme opened this issue Oct 26, 2017 · 3 comments
Labels

Comments

@Ephasme
Copy link

Ephasme commented Oct 26, 2017

Hi,

    [TestFixture]
    public class TestAutoFixture {

        public class TestClass
        {
            public string Property { get; set; }
        }

        [Test]
        public void Test()
        {
            var f = new Fixture();
            f.Customize<TestClass>(composer => composer.FromFactory(() => new TestClass { Property = "foobar" }));

            var o = f.Create<TestClass>();

            Assert.That(o.Property, Is.EqualTo("foobar"));
        }
    }

This test fails using 4.0.0-rc1 on .NET Core 2
I think this is either misleading (or poorly documented) or broken.
EDIT : It's not broken, see comments below.

@Ephasme
Copy link
Author

Ephasme commented Oct 26, 2017

I noticed that if I add .Without(_ => _.Property) after the FromFactory method it works as intended.
I think that this is very counter intuitive but since it's not a bug we can close this.

@zvirja
Copy link
Member

zvirja commented Oct 26, 2017

Well, it's likely an issue with our documentation ☺️

By default AutoFixture automatically populates properties with public setters, unless you disable that behavior by setting fixture.OmitAutoProperties = true. The composer.FromFactory() method allows you to specify how to activate the instance of the particular type, however the properties will still be assigned for the object later.

Actually, the proper AutoFixture API usage depends on the scenario. The most "idiomatic" usage in the scenario above would be the following:

f.Customize<TestClass>(c => c
    .FromFactory(() => new TestClass())
    .With(x => x.Property, "foobar"));

or even the simplified one as AutoFixture will automatically pick up that constructor:

f.Customize<TestClass>(c => c
    .With(x => x.Property, "foobar"));

Alternatively, you can simply disable the automatic properties fill-up if you need that:

f.Customize<TestClass>(c => c
    .FromFactory(() => new TestClass { Property = "foobar" })
    .OmitAutoProperties());

However, in this case, probably, the Customize<>() API is an overhead. Instead, it's simpler to use the fixture.Register() method as it allows to use the constructed instance "as-is" without any post-processing:

f.Register(() => new TestClass { Property = "foobar" });

It might be confusing at the beginning to understand which exact API suits better, but later it should go easier 😉All this API gives the flexibility and in different scenarios the different options look better.

Let me know if you still have some questions to clarify and I'll gladly help you.

P.S. The following links might also help:

P.P.S. The reason why composer.Without(x => x.Property) works is that this expression disables auto-properties for the particular property/field. In that case AutoFixture doesn't override the initial object value with the automatically generated one.

@Ephasme
Copy link
Author

Ephasme commented Oct 27, 2017

Thank you so much for this incredible answer! You're amazing :)

@Ephasme Ephasme closed this as completed Oct 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants