- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了很多天都无法解决的问题。我将 xUnit 与 given-then-when 抽象结合使用,以使测试更具可读性。
我在 EventStore 上使用包装器并运行一些集成测试。它们都运行良好.. 除了一个在并行运行时失败(并且 xUnit 并行运行),但如果我按顺序运行它们它们都会成功。
我不明白为什么这会成为一个问题,因为每个事实都应该运行构造函数(给定的)和测试的功能(何时)。在每个事实中,我都实例化了一个 Autofac ContainerBuilder
,构建容器并解析它的 IComponentContext
,因此理论上每个测试都应该按预期进行隔离和幂等。
这是我不断收到的异常:
Autofac.Core.DependencyResolutionException : An exception was thrown while activating SalesOrder.EventStore.Infra.EventStore.EventStore -> SalesOrder.EventStore.Infra.EventStore.DomainEventsRetriever -> SalesOrder.EventStore.Infra.EventStore.Factories.DomainEventFactory -> λ:SalesOrder.EventStore.Infra.EventStore.EventTypeResolver.
---- System.Reflection.ReflectionTypeLoadException : Unable to load one or more of the requested types.
Could not load type 'Castle.Proxies.IReadinessProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget) in C:\projects\autofac\src\Autofac\Core\Resolving\InstanceLookup.cs:line 136
at Autofac.Core.Resolving.InstanceLookup.Execute() in C:\projects\autofac\src\Autofac\Core\Resolving\InstanceLookup.cs:line 85
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Resolving\ResolveOperation.cs:line 130
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Resolving\ResolveOperation.cs:line 83
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) in C:\projects\autofac\src\Autofac\ResolutionExtensions.cs:line 1041
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\ResolutionExtensions.cs:line 871
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\ResolutionExtensions.cs:line 300
at SalesOrder.EventStore.Infra.EventStore.Autofac.IntegrationTests.EventStoreExtensionsTests.ResolveTests.Given_A_Container_With_Event_Store_Registered_When_Resolving_An_IEventStore.When() in C:\src\SalesOrder.EventStore\SalesOrder.EventStore.Infra.EventStore.Autofac.IntegrationTests\EventStoreExtensionsTests\ResolveTests.cs:line 53
at SalesOrder.EventStore.Infra.EventStore.Autofac.IntegrationTests.EventStoreExtensionsTests.ResolveTests.Given_A_Container_With_Event_Store_Registered_When_Resolving_An_IEventStore..ctor()
----- Inner Stack Trace -----
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
at SalesOrder.EventStore.Infra.EventStore.Autofac.EventStoreExtensions.<>c.<RegisterResolvers>b__6_2(Assembly s) in C:\src\SalesOrder.EventStore\SalesOrder.EventStore.Infra.EventStore.Autofac\EventStoreExtensions.cs:line 174
at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
at SalesOrder.EventStore.Infra.EventStore.Factories.EventTypeResolverFactory.Create(IEnumerable`1 existingTypes, IReadOnlyDictionary`2 domainEventSerializerDeserializers) in C:\src\SalesOrder.EventStore\SalesOrder.EventStore.Infra.EventStore\Factories\EventTypeResolverFactory.cs:line 16
at SalesOrder.EventStore.Infra.EventStore.Autofac.EventStoreExtensions.<>c__DisplayClass6_0.<RegisterResolvers>b__1(IComponentContext context) in C:\src\SalesOrder.EventStore\SalesOrder.EventStore.Infra.EventStore.Autofac\EventStoreExtensions.cs:line 180
at Autofac.Builder.RegistrationBuilder.<>c__DisplayClass0_0`1.<ForDelegate>b__0(IComponentContext c, IEnumerable`1 p) in C:\projects\autofac\src\Autofac\Builder\RegistrationBuilder.cs:line 62
at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Activators\Delegate\DelegateActivator.cs:line 71
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget) in C:\projects\autofac\src\Autofac\Core\Resolving\InstanceLookup.cs:line 118
这是只有一个 Fact 在与其他 Fact 并行运行时失败的测试:
public class Given_A_Container_With_Event_Store_Registered_When_Resolving_An_IEventStore
: Given_When_Then_Test
{
private IEventStore _sut;
private IComponentContext _componentContext;
protected override void Given()
{
var builder = new ContainerBuilder();
builder
.RegisterEventStore(
ctx =>
{
var eventStoreOptions =
new EventStoreOptions
{
Url = EventStoreTestConstants.TestUrl,
Port = EventStoreTestConstants.TestPort
};
return eventStoreOptions;
},
ctx =>
{
var readinessOptions =
new ReadinessOptions
{
Timeout = EventStoreTestConstants.TestTimeout
};
return readinessOptions;
});
var container = builder.Build();
_componentContext = container.Resolve<IComponentContext>();
}
protected override void When()
{
_sut = _componentContext.Resolve<IEventStore>();
}
[Fact]
public void Then_It_Should_Not_Be_Null()
{
_sut.Should().NotBeNull();
}
}
知道这里可能发生了什么吗?我看过 Autofac 的并发指南:https://autofaccn.readthedocs.io/en/latest/advanced/concurrency.html但我认为我已经正确使用了组件上下文。
更新 1: 仅供引用,这是我使用的 GivenThenWhen 模板。但这里没什么特别的(我认为!)
namespace ToolBelt.TestSupport
{
public abstract class Given_When_Then_Test
: IDisposable
{
protected Given_When_Then_Test()
{
Setup();
}
private void Setup()
{
Given();
When();
}
protected abstract void Given();
protected abstract void When();
public void Dispose()
{
Cleanup();
}
protected virtual void Cleanup()
{
}
}
public abstract class Given_WhenAsync_Then_Test
: IDisposable
{
protected Given_WhenAsync_Then_Test()
{
Task.Run(async () => { await SetupAsync(); }).GetAwaiter().GetResult();
}
private async Task SetupAsync()
{
Given();
await WhenAsync();
}
protected abstract void Given();
protected abstract Task WhenAsync();
public void Dispose()
{
Cleanup();
}
protected virtual void Cleanup()
{
}
}
}
更新 2: 这是我用于实现和所有测试的 IoCC Autofac 注册方法。有点复杂,因为我使用反射来保持 EventStore 包装器完全通用,但以防万一有人在那里看到可能影响测试的时髦东西..
public static class EventStoreExtensions
{
public static void RegisterEventStore(
this ContainerBuilder builder,
Func<IComponentContext, EventStoreOptions> optionsRetriever,
Func<IComponentContext, ReadinessOptions> readinessOptionsRetriever,
Func<IComponentContext, CustomDomainEventMappersOptions> customDomainEventMappersOptionsRetriever = null)
{
RegisterEventStoreConnection(builder, optionsRetriever);
RegisterFactories(builder);
RegisterEventStoreManager(builder);
RegisterConverters(builder);
RegisterResolvers(builder, customDomainEventMappersOptionsRetriever);
RegisterEventStoreServices(builder);
RegisterEventStoreReadinessCheck(builder, readinessOptionsRetriever);
}
private static void RegisterEventStoreReadinessCheck(
ContainerBuilder builder,
Func<IComponentContext, ReadinessOptions> readinessOptionsRetriever)
{
builder
.Register(context =>
{
var ctx = context.Resolve<IComponentContext>();
var readinessOptions = readinessOptionsRetriever.Invoke(ctx);
var timeout = readinessOptions.Timeout;
var eventStoreConnection = context.Resolve<IEventStoreConnection>();
var eventStoreReadiness =
new EventStoreReadiness(
eventStoreConnection,
timeout);
return eventStoreReadiness;
})
.As<IEventStoreReadiness>()
.As<IReadiness>()
.SingleInstance();
}
private static void RegisterEventStoreConnection(
ContainerBuilder builder,
Func<IComponentContext, EventStoreOptions> optionsRetriever)
{
builder
.Register(context =>
{
var ctx = context.Resolve<IComponentContext>();
var eventStoreOptions = optionsRetriever.Invoke(ctx);
ConnectionSettings connectionSetting =
ConnectionSettings
.Create()
.KeepReconnecting();
var urlString = eventStoreOptions.Url;
var port = eventStoreOptions.Port;
var ipAddress = IPAddress.Parse(urlString);
var tcpEndPoint = new IPEndPoint(ipAddress, port);
var eventStoreConnection = EventStoreConnection.Create(connectionSetting, tcpEndPoint);
return eventStoreConnection;
})
.As<IEventStoreConnection>()
.SingleInstance();
}
private static void RegisterFactories(
ContainerBuilder builder)
{
builder
.RegisterType<DomainEventFactory>()
.As<IDomainEventFactory>()
.SingleInstance();
builder
.RegisterType<EventDataFactory>()
.As<IEventDataFactory>()
.SingleInstance();
builder
.RegisterType<ExpectedVersionFactory>()
.As<IExpectedVersionFactory>()
.SingleInstance();
builder
.RegisterType<IdFactory>()
.As<IIdFactory>()
.SingleInstance();
builder
.RegisterType<StreamNameFactory>()
.As<IStreamNameFactory>()
.SingleInstance();
builder
.RegisterType<RetrievedEventFactory>()
.As<IRetrievedEventFactory>()
.SingleInstance();
}
private static void RegisterEventStoreManager(ContainerBuilder builder)
{
builder
.RegisterType<EventStoreManager>()
.As<IEventStoreManager>()
.SingleInstance();
}
private static void RegisterConverters(ContainerBuilder builder)
{
builder
.Register(context =>
{
var utf8Encoding = new BytesConverter(Encoding.UTF8);
return utf8Encoding;
})
.As<IBytesConverter>()
.SingleInstance();
builder
.RegisterType<NewtonsoftConverter>()
.As<IJsonConverter>()
.SingleInstance();
}
private static void RegisterResolvers(
ContainerBuilder builder,
Func<IComponentContext, CustomDomainEventMappersOptions> customDomainEventMappersOptionsRetriever)
{
builder
.Register(context =>
{
var ctx = context.Resolve<IComponentContext>();
var customDomainEventMappersOptions = customDomainEventMappersOptionsRetriever?.Invoke(ctx);
var domainEventSerializerDeserializers =
customDomainEventMappersOptions?.DomainEventSerializerDeserializers;
var mapperResolver = MapperResolverFactory.Create(domainEventSerializerDeserializers);
return mapperResolver;
})
.As<IMapperResolver>()
.SingleInstance();
builder
.Register(context =>
{
var ctx = context.Resolve<IComponentContext>();
var assembliesLoaded = AppDomain.CurrentDomain.GetAssemblies();
var domainEventTypes =
assembliesLoaded
.SelectMany(s => s.GetTypes())
.Where(x => typeof(IDomainEvent).IsAssignableFrom(x)
&& x.IsClass);
var customDomainEventMappersOptions = customDomainEventMappersOptionsRetriever?.Invoke(ctx);
var domainEventSerializerDeserializers =
customDomainEventMappersOptions?.DomainEventSerializerDeserializers;
var typeResolver =
EventTypeResolverFactory.Create(
domainEventTypes,
domainEventSerializerDeserializers);
return typeResolver;
})
.As<IEventTypeResolver>()
.SingleInstance();
}
private static void RegisterEventStoreServices(ContainerBuilder builder)
{
builder
.RegisterType<EventStoreRepository>()
.As<IEventStoreRepository>();
builder
.RegisterType<DomainEventsPersister>()
.As<IDomainEventsPersister>();
builder
.RegisterType<DomainEventsRetriever>()
.As<IDomainEventsRetriever>();
builder
.RegisterType<EventStore>()
.As<IEventStore>();
}
}
更新 3: 这是整个存储库,以防有人感到无聊并想尝试复制它。它是一个通用事件存储包装器,用于使用官方 C# 驱动程序为 Greg Young 的事件存储产品实现的事件源。
https://gitlab.com/DiegoDrivenDesign/DiDrDe.EventStore
有趣的是,这个问题似乎每隔一段时间就会消失一次。事实上,通常在重新启动 PC 后,所有测试都会正常通过。其他时候它没有,所以我怀疑它与我在运行时加载程序集并且有些东西不正常的事实有关:(
2021 年 9 月 9 日更新我所做的异步执行并不完全正确。有一种方法可以使用 xUnit 进行异步执行,这可能在这种竞争条件下发挥了作用。这是我所有测试继承自的 given-when-then
模式的更好实现。感谢 IAsyncLifetime
,我能够异步(并等待)先决条件和操作本身。
using System.Threading.Tasks;
using Xunit;
namespace Rubiko.TestSupport.XUnit
{
public abstract class Given_When_Then_Test_Async
: IAsyncLifetime
{
public async Task InitializeAsync()
{
await Given();
await When();
}
public async Task DisposeAsync()
{
await Cleanup();
}
protected virtual Task Cleanup()
{
return Task.CompletedTask;
}
protected abstract Task Given();
protected abstract Task When();
}
}
最佳答案
DynamicProxyGenAssembly2 是通过模拟使用 CaSTLeProxy 的系统构建的临时程序集。 NSubstitute 和 Moq 有一些类似的未解决问题,表明问题是 CaSTLe.Core 甚至 .Net Framework 中的竞争条件(有关详细信息,请参阅:TypeLoadException or BadImageFormatException under heavy multi-threaded proxy generation)
关于c# - 与 Autofac 并行运行 xUnit 集成测试时无法加载类型 CaSTLe.Proxies.IReadinessProxy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56254916/
我正在实现 hangFire,它是我项目中的作业调度库。 我面临着与此 link 中相同的问题 然而,将 LifestylePerWebRequest() 替换为 HybridPerWebReques
在我的项目中,我需要同时使用 CaSTLe.Windsor 和 Moq dll。 Windsor 要求 CaSTLe.Core 也在项目中被引用。 当我尝试使用 CaSTLe.Core 中的方法时,问
我已将我的解决方案从城堡版本 1.0 更新到版本 3.0,现在我收到此错误: Type Castle.Facilities.FactorySupport.FactorySupportFacility
我的应用程序使用“SignalR”客户端/服务器通信框架。如果您不熟悉它,服务器端应用程序通常包含一个或多个“集线器”类(类似于 asmx 网络服务),每个类都提供可由客户端调用的方法。在启动期间,客
假设我有这样的组件 public class MyComponent { public MyComponent(string name) { } } 我基本上想让提供的构造函数
我想知道是否有一些最佳实践来实现我需要的功能。 我有一个 Web 应用程序,它在启动期间通过反射扫描某些程序集(插件)并针对公共(public)内核注册它们的依赖项。 外部库可能需要相同的依赖项。 例
我想知道是否有一些最佳实践来实现我需要的功能。 我有一个 Web 应用程序,它在启动期间通过反射扫描某些程序集(插件)并针对公共(public)内核注册它们的依赖项。 外部库可能需要相同的依赖项。 例
是否有关于如何使用 CaSTLe Windsor 的自动事务管理的任何简单示例? documentation似乎缺少一些信息。我看到有用于 nHibernate、ActiveRecord 等的工具……
这是一次回答,但从那时起下载站点已经改变(显然)。我根本找不到 CaSTLe.MicroKernel。 2.51 不能再下载,它不在 2.52 中。或 2.53。 最佳答案 没有Castle.Micr
我正在将我们的项目从 .Net 2 升级到 .Net4.5,同时我将尽可能多的引用推送到 NuGet 并确保版本是最新的。 我在运行其中一项测试时遇到问题 测试类: public cl
当我开始使用 Windsor 时,我认为 DI 会很简单。现在它让我越来越困惑。 在我看来,存储库是一个具有单例生命周期的类。我应该有一个 FooRepository 实例来在应用程序的生命周期内将
我有一个接口(interface) ISession,其实例由不同的 session 工厂生成,具体取决于类所属的命名空间。 我的组件注册示例: IWindsorContainer container
我正在关注 example by José F. Romaniello使用 NHibernate 进行 session 管理。这是一篇非常好的文章,但是我在 NHibernate、Windsor 和
我有一个看似简单的用例。有一个 ICsvReader 组件。让我们在这里简单地将它命名为 Reader。我们加载了一组已知的 CSV 文件,其中一些有标题,有些没有。目前有多个阅读器:Reader_S
试图找出这件事的真正原因,但并没有太多乐趣! Type is not resolved for member 'Castle.MicroKernel.Lifestyle.Scoped.CallCont
这是我在 Global.asax 中的代码 WindsorContainer container = new WindsorContainer(); container.Register(Compo
我正在尝试了解如何使用 CaSTLe ActiveRecord 执行自定义查询。 我能够运行返回我的实体的简单查询,但我真正需要的是如下所示的查询(带有自定义字段集): 选择 count(1) 作为
在使用 ArrayResolver 时,如果我注册了一个接口(interface)的多个实现和一个依赖于所述接口(interface)数组的类,我希望数组解析器注入(inject)所有可以成功解析的接
我为服务注册了两个组件: container.Register( Component.For().Named("FirstChoice").ImplementedBy... Compo
有没有人有一些使用城堡 Windsor InstallerFactory 来订购安装程序的示例代码? 似乎无法在文档或其他地方找到它。 干杯 最佳答案 您只能使用 InstallerFactory与
我是一名优秀的程序员,十分优秀!