I am trying to use AutoFixture to simplify my life.
How do I mock a class with
Example
public class User
{
private User(){}
/// <summary>
/// Created by Database...
/// </summary>
public long? Id { get; protected set; }
public string Name { get; protected set; }
public static User Create(string name)
{
var user = new User {Name = name};
return user;
}
}
I've tried using a combo of Factory and SpecimenBuilder:
[Fact]
public void CreatingUserWithId_Should_Work_UsingFactoryAndSpecimenBuilder()
{
IFixture fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());
fixture.Customizations.Add(new UserBuilder());
fixture.Customize<User>(o => o.FromFactory(() => User.Create("foo")));
var user = fixture.Create<User>();
user.Should().NotBeNull();
user.Id.Should().HaveValue();
}
with
public class UserBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var pi = request as PropertyInfo;
if (pi == null) return new NoSpecimen(request);
// The following code only works for public properties... :-(
if (pi.Name == "Id" && pi.PropertyType == typeof (long?)) return 42;
return new NoSpecimen(request);
}
}
A demo C# solution is available at https://github.com/draptik/MockingStaticCreate
Thankful for any pointers,
Patrick
AF will do the right thing ( User.Create()
with an anonymous name arg) with no customizations whatsoever.
The only missing bit is setting the Id
. Which is a question you'll have to answer for yourself -- how should your consuming code do this in the first place ? When you've decided, you could do fixture.Customize<User>( c => c.FromFactory( User.Create).Do( x => ???)
Perhaps you could consider exposing a ctor that takes an id
too. Then you can do a Customize<User>
... GreedyConstructorQuery
.
If your ORM is doing some wacky reflection and you like that and/or can't route around it you get to choose whether for your tests you should:
a) do that too - if that's relevant to a given test or set of tests
b) consider that to be something that just works
Regarding mixing mocking and feeding in of values to an Entity or Value object - Don't do that ( Mark Seemann's Commands vs Queries article might help you here). The fact that you seem to be needing/wanting to do so makes it seems you're trying to be too ambitions in individual tests - are you finding the simplest thing to test and trying to have a single Assert
testing one thing with minimal setup.
Go buy the GOOS book - it'll help you figure out ways of balancing these kinds of trade-offs.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.