【发布时间】:2016-05-31 02:00:49
【问题描述】:
使用 FakeItEasy 的单元测试在尝试伪造简单的接口时随机失败。它偶尔会在不同的测试中出现,并且不稳定。
这是我需要伪造的示例界面:
public interface IJobSuiteFilterApplier
{
JobSuiteDto FilterJobSuites(JobSuiteDto jobSuiteDto, JobSuiteFilter jobSuiteFilter);
}
这是一段创建假的代码,有时会失败:
var jobSuiteFilterApplier = A.Fake<IJobSuiteFilterApplier>(x => x.Strict());
这里是异常详情:
FakeItEasy.Core.FakeCreationException:
Failed to create fake of type "QS.TestShell.Server.ExecutionPlanner.Queries.IExecutionPlannerQueryService".
Below is a list of reasons for failure per attempted constructor:
No constructor arguments failed:
No usable default constructor was found on the type QS.TestShell.Server.ExecutionPlanner.Queries.IExecutionPlannerQueryService.
An exception was caught during this call. Its message was:
Collection was modified; enumeration operation may not execute.
at FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithResolvedConstructors(Type typeOfFake, String reasonForFailureOfUnspecifiedConstructor, IEnumerable`1 resolvedConstructors)
at FakeItEasy.Creation.FakeObjectCreator.TryCreateFakeWithDummyArgumentsForConstructor(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, String failReasonForDefaultConstructor, Boolean throwOnFailure)
at FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, Boolean throwOnFailure)
at FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, FakeOptions options)
at FakeItEasy.Creation.DefaultFakeCreatorFacade.CreateFake[T](Action`1 options)
at FakeItEasy.A.Fake[T](Action`1 options)
当我添加以下内容时,测试通过了,但是我需要将其添加到所有虚假创作中看起来很奇怪:
var jobSuiteFilterApplier = A.Fake<IJobSuiteFilterApplier>(x => x.Strict().Synchronized());
public class CallSynchronizer : IInterceptionListener
{
private static readonly object SynchronizationLock = new object();
public void OnBeforeCallIntercepted(IFakeObjectCall interceptedCall)
{
Monitor.Enter(SynchronizationLock);
}
public void OnAfterCallIntercepted(ICompletedFakeObjectCall interceptedCall, IFakeObjectCallRule ruleThatWasApplied)
{
Monitor.Exit(SynchronizationLock);
}
}
public static class MyPersonalFakeExtensions
{
public static IFakeOptionsBuilder<T> Synchronized<T>(this IFakeOptionsBuilder<T> builder)
{
return builder.OnFakeCreated(fake => Fake.GetFakeManager(fake).AddInterceptionListener(new CallSynchronizer()));
}
}
更新:我正在开发人员机器上使用 ReSharper 测试运行程序运行测试,并在构建服务器上使用 mstext.exe。并发设置允许一次运行多个测试。
【问题讨论】:
-
你使用什么单元测试框架?您是在并行运行单元测试还是在多个线程上创建伪造品?那似乎是open issue。
-
抱歉没有提及。我正在使用 FakeItEasy。我正在开发人员机器上使用 ReSharper 测试运行程序并在构建服务器上使用 mstext.exe 运行测试。
标签: c# unit-testing mocking fakeiteasy