使用FakeItEasy的單元測試在嘗試僞造簡單的intefrace時會隨機失敗。偶爾出現在不同的測試中,並且不穩定。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)
當我添加以下內容時,測試通過,但是看起來很奇怪,我需要將它添加到所有fa柯創作:
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。併發設置允許一次運行多個測試。
你使用什麼單元測試框架?你是在並行運行單元測試還是在多線程上創建假貨?這似乎是一個[公開問題](https://github.com/FakeItEasy/FakeItEasy/issues/60)。 – 2014-10-22 07:10:21
抱歉沒有提及它。我正在使用FakeItEasy。我正在開發人員機器上使用ReSharper測試運行器運行測試,並在構建服務器上使用mstext.exe。 – 2014-10-22 07:15:53