Модульные тесты, которые используют 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 создание Ke:
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). –
Извините, что не упоминал об этом. Я использую FakeItEasy. Я запускаю тесты с помощью тестового бегуна ReSharper на машине разработчика и используя mstext.exe на сервере сборки. –