- 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/
有没有办法同时运行 2 个不同的代码块。我一直在研究 R 中的并行包,它们似乎都基于在循环中运行相同的函数。我正在寻找一种同时运行不同函数的方法(循环的 1 次迭代)。例如,我想在某个数据对象上创建一
无论如何增加 Parallel.For 启动后的循环次数?示例如下: var start = 0; var end = 5; Parallel.For(start, end, i => { C
我是 Golang 的新手,正在尝试了解并发和并行。我阅读了下面提到的关于并发和并行的文章。我执行了相同的程序。但没有得到相同的(混合字母和字符)输出。首先获取所有字母,然后获取字符。似乎并发不工作,
我正在寻找同时迭代 R 中两个或多个字符向量/列表的方法,例如。有没有办法做这样的事情: foo <- c('a','c','d') bar <- c('aa','cc','dd') for(i in
我对 Raku 很陌生,我对函数式方法有疑问,尤其是 reduce。 我最初有这样的方法: sub standardab{ my $mittel = mittel(@_); my $foo =
我最近花了很多时间来学习实时音频处理的细节,我发现的大多数库/工具都是c / c++代码或脚本/图形语言的形式,并在其中编译了c / c++代码。引擎盖。 使用基于回调的API,与GUI或App中的其
我正在使用 JMeter 进行图像负载测试。我有一个图像名称数组并遍历该数组,我通过 HTTP 请求获取所有图像。 -> loop_over_image - for loop controller
我整个晚上都在困惑这个问题...... makeflags = ['--prefix=/usr','--libdir=/usr/lib'] rootdir='/tmp/project' ps = se
我正在尝试提高计算图像平均值的方法的性能。 为此,我使用了两个 For 语句来迭代所有图像,因此我尝试使用一个 Parallel For 来改进它,但结果并不相同。 我做错了吗?或者是什么导致了差异?
假设您有一个并行 for 循环实现,例如ConcRT parallel_for,将所有工作放在一个 for 循环体内总是最好的吗? 举个例子: for(size_t i = 0; i < size()
我想并行运行一部分代码。目前我正在使用 Parallel.For 如何让10、20或40个线程同时运行 我当前的代码是: Parallel.For(1, total, (ii) =>
我使用 PAY API 进行了 PayPal 自适应并行支付,其中无论用户(买家)购买什么,都假设用户购买了总计 100 美元的商品。在我的自适应并行支付中,有 2 个接收方:Receiver1 和
我正在考虑让玩家加入游戏的高效算法。由于会有大量玩家,因此算法应该是异步的(即可扩展到集群中任意数量的机器)。有细节:想象有一个无向图(每个节点都是一个玩家)。玩家之间的每条边意味着玩家可以参加同一场
我有一个全局变量 volatile i = 0; 和两个线程。每个都执行以下操作: i++; System.out.print(i); 我收到以下组合。 12、21 和 22。 我理解为什么我没有得到
我有以下称为 pgain 的方法,它调用我试图并行化的方法 dist: /***************************************************************
我有一个 ruby 脚本读取一个巨大的表(约 2000 万行),进行一些处理并将其提供给 Solr 用于索引目的。这一直是我们流程中的一大瓶颈。我打算在这里加快速度,我想实现某种并行性。我对 Ru
我正在研究 Golang 并遇到一个问题,我已经研究了几天,我似乎无法理解 go routines 的概念以及它们的使用方式。 基本上我是在尝试生成数百万条随机记录。我有生成随机数据的函数,并将创建一
我希望 for 循环使用 go 例程并行。我尝试使用 channel ,但没有用。我的主要问题是,我想在继续之前等待所有迭代完成。这就是为什么在它不起作用之前简单地编写 go 的原因。我尝试使用 ch
我正在使用 import Control.Concurrent.ParallelIO.Global main = parallel_ (map processI [1..(sdNumber runPa
我正在尝试通过 makePSOCKcluster 连接到另一台计算机: library(parallel) cl ... doTryCatch -> recvData -> makeSOCKm
我是一名优秀的程序员,十分优秀!