![](/img/trans.png)
[英]Differences between singleton/static class/instance class with a private ctor?
[英]Mocking a class with private ctor and static create method and private id property
我正在嘗試使用AutoFixture簡化生活。
我該如何模擬課程
例
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;
}
}
我試過使用Factory和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();
}
同
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);
}
}
可在https://github.com/draptik/MockingStaticCreate上獲得演示C#解決方案
感謝任何指示,
帕特里克
AF將做正確的事情( User.Create()
帶有一個匿名名稱arg),而無需進行任何自定義。
唯一缺少的位是設置Id
。 您必須自己回答一個問題-您的使用代碼首先應該如何做到這一點? 確定后,就可以進行fixture.Customize<User>( c => c.FromFactory( User.Create).Do( x => ???)
也許您可以考慮公開一個帶有id
的ctor。 然后,您可以執行Customize<User>
... GreedyConstructorQuery
。
如果您的ORM做一些古怪的思考,並且您喜歡這樣做和/或無法繞過它,則可以選擇是否要進行測試:
a)也這樣做-如果這與給定測試或一組測試相關
b)認為這是行之有效的
關於混合模擬和將值饋入到Entity或Value對象中-請勿這樣做( Mark Seemann的Commands vs Queries文章可能會對您有所幫助)。 您似乎需要/想要這樣做的事實似乎使您似乎想在單個測試中過於野心-您是否在尋找最簡單的測試並嘗試以最少的設置進行單個Assert
測試。
快去購買GOOS書吧 -它會幫助您找到平衡這些折衷方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.