我正在尝试验证我的基础架构。 AutoFixture说我的代码中有一个循环引用,当我省略该行为时,它无法将样本转换为我的对象类型。
绘制解决方案依赖关系图表没有循环引用。 autofixture的输出似乎给了我一个域对象指向域对象的路径。我不明白......他们很清楚。
我会继续前进,因为我有一个测试通过,但我真的想确保我没有不需要的循环引用。我还担心如果在这个例子中没有构建我的简单域对象,我将无法在以后使用AutoFixture进行隔离组件。
以下是成功的测试:
[Fact]
[UseDataService(typeof(DatabaseVersionService))]
public void DataServiceGetsDatabaseVersionNonAutoFixture()
{
var sut = new VersionClientProxy(new Uri(ConfigurationManager.AppSettings["DataServiceHostAddress"]));
var expected = new DatabaseVersion()
{
MajorVersionId = 0,
MinorVersionId = 0,
BuildVersionId = 0,
VersionId = 1
};
var actual = (from a in sut.DatabaseVersions
orderby a.VersionId descending
select a).FirstOrDefault();
Assert.Equal(expected.MajorVersionId, actual.MajorVersionId);
Assert.Equal(expected.MinorVersionId, actual.MinorVersionId);
Assert.Equal(expected.BuildVersionId, actual.BuildVersionId);
Assert.Equal(expected.VersionId, actual.VersionId);
}
以下测试失败:
[Fact]
[UseDataService(typeof(DatabaseVersionService))]
public void DataServiceGetsDatabaseVersion()
{
var fixture = new Fixture();
var sut = fixture.Build<VersionClientProxy>().FromFactory<VersionClientProxy>((x) =>
{
return new VersionClientProxy(new Uri(ConfigurationManager.AppSettings["DataServiceHostAddress"]));
}).CreateAnonymous();
var version = fixture.Build<DatabaseVersion>().FromFactory<DatabaseVersion>((x) =>
{
return new DatabaseVersion { MajorVersionId = 0, MinorVersionId = 0, BuildVersionId = 0, VersionId = 1 };
}).CreateAnonymous();
var expected = version.AsSource().OfLikeness<DatabaseVersion>();
var actual = (from a in sut.DatabaseVersions
orderby a.VersionId descending
select a).FirstOrDefault();
Assert.True(expected.Equals(actual));
}
这是客户端代理(单独的项目仅引用数据模型项目):
public class VersionClientProxy : DataServiceContext
{
public VersionClientProxy(Uri serviceRoot)
: base(serviceRoot, DataServiceProtocolVersion.V3)
{
}
public IQueryable<DatabaseVersion> DatabaseVersions
{
get { return CreateQuery<DatabaseVersion>("DatabaseVersions"); }
}
}
这是我启动的数据服务(服务在单独的项目引用中只有数据模型项目)
public class UseDataServiceAttribute : BeforeAfterTestAttribute
{
private readonly DataServiceHost serviceHost;
public UseDataServiceAttribute(Type serviceToHost)
{
serviceHost = new DataServiceHost(serviceToHost, new Uri[] { new Uri(ConfigurationManager.AppSettings["DataServiceHostAddress"]) });
}
public override void Before(System.Reflection.MethodInfo methodUnderTest)
{
try { serviceHost.Open(); }
catch
{
try { serviceHost.Close(); }
catch
{
try { serviceHost.Abort(); }
catch { }
}
}
base.Before(methodUnderTest);
}
public override void After(System.Reflection.MethodInfo methodUnderTest)
{
base.After(methodUnderTest);
try { serviceHost.Close(); }
catch
{
try { serviceHost.Abort(); }
catch { }
}
}
}
这是数据模型类(由所有其他项目引用的单独项目):
public class DatabaseVersionDataModel
{
private readonly List<DatabaseVersion> templist;
public DatabaseVersionDataModel()
{
templist = new List<DatabaseVersion> {
new DatabaseVersion() {
MajorVersionId = 0,
MinorVersionId = 0,
BuildVersionId = 0,
VersionId = 1 }
};
DatabaseVersions = templist.AsQueryable();
}
public IQueryable<DatabaseVersion> DatabaseVersions { get; private set; }
}
以下是模型项目中的数据库版本类:
[DataServiceKey("VersionId")]
public class DatabaseVersion
{
public int VersionId { get; set; }
public int MajorVersionId { get; set; }
public int MinorVersionId { get; set; }
public int BuildVersionId { get; set; }
}
这是我的数据服务项目中的DatabaseVersionService.svc文件(空的asp.net,编译,调试iisexpress和atom或json是可浏览的):
public class DatabaseVersionService : DataService<DatabaseVersionDataModel>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
// config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
这是删除throwrecursionbehavior并添加omitonrecursionbehavior之后的输出:
结果消息:System.InvalidCastException:无法将类型为“Ploeh.AutoFixture.Kernel.OmitSpecimen”的对象强制转换为“skeletor.Domain.DatabaseVersion”。 结果StackTrace:
在Ploeh.AutoFixture.Kernel.SpecimenFactory2.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.NoSpecimenOutputGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.Postprocessor
1.Create(对象请求,ISpecimenContext上下文) 在Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder。&lt;&gt; c_ DisplayClass6.b _1(ISpecimenBuilder b) 在System.Linq.Enumerable.WhereSelectListIterator2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext() 在System.Linq.Enumerable.d_ a51.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1来源) 在Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(对象请求,ISpecimenContext上下文) 在Ploeh.AutoFixture.Kernel.FilteringSpecimenBuilder.Create(对象请求,ISpecimenContext上下文) 在Ploeh.AutoFixture.Dsl.NodeComposer1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.<>c__DisplayClass6.<Create>b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectListIterator
2.MoveNext() 在System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.<DefaultIfEmptyIterator>d__a5
1.MoveNext() at System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Dsl.CompositeNodeComposer
1.Create(Object request,ISpecimenContext context) 在Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(对象请求) 在Ploeh.AutoFixture.Kernel.SpecimenFactory2.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.NoSpecimenOutputGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.Postprocessor
1.Create(对象请求,ISpecimenContext上下文) 在Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder。&lt;&gt; c _DisplayClass6.b_ 1(ISpecimenBuilder b) 在System.Linq.Enumerable.WhereSelectListIterator2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext() 在System.Linq.Enumerable.d _a51.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1来源) 在Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(对象请求,ISpecimenContext上下文) 在Ploeh.AutoFixture.Kernel.FilteringSpecimenBuilder.Create(对象请求,ISpecimenContext上下文) 在Ploeh.AutoFixture.Dsl.NodeComposer1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.<>c__DisplayClass6.<Create>b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectListIterator
2.MoveNext() 在System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.<DefaultIfEmptyIterator>d__a5
1.MoveNext() at System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Dsl.CompositeNodeComposer
1.Create(Object request,ISpecimenContext context) 在Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(对象请求) 在Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous [T](ISpecimenContext context,T seed) 在Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous [T](ISpecimenContext context) 在Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous [T](ISpecimenBuilderComposer composer) 在Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous [T](IPostprocessComposer`1作曲家) 在skeletor.AcceptanceTests.InfrstructureTests.DataServiceGetsDatabaseVersion()在d:\ projects \ skeletor \ skeletor.AcceptanceTests \ InfrstructureTests.cs:第31行
答案 0 :(得分:4)
假设您使用WCF Data Services 5. * for OData V3,您可以尝试以下操作:
与任何其他生成的标本一样,可以完全接管它的创建。我们可以按如下方式自定义任何Uri
的创建:
public class CustomUriBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (request == typeof(Uri))
{
return new Uri(
ConfigurationManager.AppSettings["DataServiceHostAddress"]);
}
return new NoSpecimen(request);
}
}
使用上述自定义ISpecimenBuilder
类型,每次请求Uri
时,都会返回预定义的Uri
。
现在可以重写测试DataServiceGetsDatabaseVersion
:
[Fact]
[UseDataService(typeof(DatabaseVersionService))]
public void DataServiceGetsDatabaseVersion()
{
var fixture = new Fixture();
fixture.Customize<VersionClientProxy>(c => c.OmitAutoProperties());
fixture.Customizations.Add(new CustomUriBuilder());
fixture.Inject(
new DatabaseVersion
{
MajorVersionId = 0,
MinorVersionId = 0,
BuildVersionId = 0,
VersionId = 1
});
var sut = fixture.CreateAnonymous<VersionClientProxy>();
var version = fixture.CreateAnonymous<DatabaseVersion>();
var expected = version.AsSource().OfLikeness<DatabaseVersion>();
var actual = (from a in sut.DatabaseVersions
orderby a.VersionId descending
select a).FirstOrDefault();
Assert.True(expected.Equals(actual));
}
希望有所帮助。