![](/img/trans.png)
[英]Create WPF DataTemplate depending on a class attribute concrete type (not class type)
[英]Create concrete type for abstract property depending on context
我有以下類型層次結構:
public abstract class ResourceId
{
}
public class CarId : ResourceId
{
}
public class PlaneId: ResourceId
{
}
public interface IResource
{
ResourceId Id { get; set; }
}
public class Plane : IResource
{
public ResourceId Id { get; set; }
}
public class Car : IResource
{
public ResourceId Id { get; set; }
}
我希望AutoFixture在嘗試創建Plane或Car時創建“正確”類型的ResourceId。
我試過用:
_fixture.Customize<Plane>(composer =>
composer.With(h => h.Id, _fixture.Create<PlaneId>()));
但是,當然會為每個實例創建相同的ID。 我希望每個人都有一個唯一的ID。
對此最好的方法是什么?
這是一個簡單的方法來做你想要的:
[Fact]
public void HowToUseFixtureToCreatePlanesWithNewIds()
{
var fixture = new Fixture();
fixture.Customize<Plane>(c => c
.Without(p => p.Id)
.Do(p => p.Id = fixture.Create<PlaneId>()));
var planes = fixture.CreateMany<Plane>();
Assert.True(planes.Select(p => p.Id).Distinct().Count() > 1);
}
但是,如果我是你,我會認真考慮簡化那個類層次結構......
有一種方法可以滿足您的要求,但它需要一種鮮為人知的自定義API: Register
方法。
Register
的目的是允許用戶為特定類型指定工廠功能 。 然后,AutoFixture將該類型對象的創建委托給該函數。
Register
一個顯着特點是它能夠提供匿名對象,以便在需要時將其作為參數傳遞給工廠函數 。 它通過一些重載來實現。 以下是一些示例 :
Register<T>(Func<T> factory)
不向Register<T>(Func<T> factory)
提供任何參數 Register<T1, T>(Func<T1, T> factory)
提供一個T1
類型的參數來創建T
類型的對象 Register<T1, T2, T>(Func<T1, T2, T> factory)
提供T1
和T2
類型的兩個參數來創建T
類型的對象 現在,我們可以使用此功能通過將CarId
和PlanId
匿名實例分配給其Id
屬性來自定義Car
和Plane
類型的對象:
[Fact]
public void Test()
{
var fixture = new Fixture();
fixture.Register<CarId, Car>(id =>
{
var resource = new Car { Id = id };
return resource;
});
fixture.Register<PlaneId, Plane>(id =>
{
var resource = new Plane { Id = id };
return resource;
});
Assert.NotSame(fixture.Create<Car>().Id, fixture.Create<Car>().Id);
Assert.NotSame(fixture.Create<Plane>().Id, fixture.Create<Plane>().Id);
}
此測試通過,因為傳遞給工廠函數的CarId
和PlanId
對象是由AutoFixture創建的 ,因此每次都不同。
您必須為每個類自定義創建算法,在此示例中為Car
和Plane
,如以下傳遞測試所示:
[Fact]
public void Test()
{
var fixture = new Fixture();
fixture.Customize<Plane>(c => c
.With(x => x.Id, fixture.Create<PlaneId>()));
fixture.Customize<Car>(c => c
.With(x => x.Id, fixture.Create<CarId>()));
var plane = fixture.Create<Plane>();
var car = fixture.Create<Car>();
Assert.IsType<PlaneId>(plane.Id);
Assert.IsType<CarId>(car.Id);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.