public static SelfInitializingFake <TService> For <TConcreteService>( Func <TConcreteService> serviceFactory, IRecordedCallRepository repository) where TConcreteService : TService { if (serviceFactory == null) { throw new ArgumentNullException(nameof(serviceFactory)); } if (repository == null) { throw new ArgumentNullException(nameof(repository)); } return(new SelfInitializingFake <TService>(() => serviceFactory.Invoke(), repository)); }
public static void CreateFromInitializedRepository( IRecordedCallRepository repository, Func <IService> serviceFactory, SelfInitializingFake <IService> fake) { "Given a saved call repository" .x(() => repository = A.Fake <IRecordedCallRepository>()); "And the repository has been initialized" .x(() => A.CallTo(() => repository.Load()).Returns(Enumerable.Empty <RecordedCall>())); "And a service factory" .x(() => serviceFactory = A.Fake <Func <IService> >()); "When I create a self-initializing fake" .x(() => fake = SelfInitializingFake <IService> .For(serviceFactory, repository)); "Then the factory is not invoked" .x(() => A.CallTo(serviceFactory).MustNotHaveHappened()); }
public static void CreateFromRepositoryAndServiceFactory( IRecordedCallRepository repository, Func <IService> serviceFactory, SelfInitializingFake <IService> fake) { "Given a saved call repository" .x(() => repository = A.Fake <IRecordedCallRepository>()); "And a service factory" .x(() => serviceFactory = A.Fake <Func <IService> >()); "When I create a self-initializing fake" .x(() => fake = SelfInitializingFake <IService> .For(serviceFactory, repository)); "Then the self-initializing fake is created" .x(() => fake.Should().NotBeNull()); "And its Fake property is not null" .x(() => fake.Object.Should().NotBeNull()); }
public static void CreateFromNullCallRepository( IRecordedCallRepository repository, Func <IService> serviceFactory, Exception exception) { "Given a service factory" .x(() => serviceFactory = A.Fake <Func <IService> >()); "And a null saved call repository" .x(() => repository = null); "When I create a self-initializing fake" .x(() => exception = Record.Exception(() => SelfInitializingFake <IService> .For(serviceFactory, repository))); "Then the constructor throws an exception" .x(() => exception.Should() .BeOfType <ArgumentNullException>() .Which.ParamName.Should().Be("repository")); }
public static void CreateFromDerivedFactoryType( IRecordedCallRepository repository, Func <Service> serviceFactory, SelfInitializingFake <IService> fake) { "Given a saved call repository" .x(() => repository = A.Fake <IRecordedCallRepository>()); "And the repository has not been initialized" .x(() => A.CallTo(() => repository.Load()).Returns(null)); "And a service factory that creates a derived type" .x(() => serviceFactory = A.Fake <Func <Service> >()); "When I create a self-initializing fake" .x(() => fake = SelfInitializingFake <IService> .For <IService>(serviceFactory, repository)); "Then the factory is invoked to create the service" .x(() => A.CallTo(serviceFactory).MustHaveHappened()); }
/// <summary> /// Initializes a new instance of the <see cref="SelfInitializingFake{TService}"/> class. /// </summary> /// <param name="serviceFactory">A factory that will create a concrete service if needed.</param> /// <param name="repository">A source of saved call information, or sink for the same.</param> internal SelfInitializingFake(Func <TService> serviceFactory, IRecordedCallRepository repository) { if (serviceFactory == null) { throw new ArgumentNullException(nameof(serviceFactory)); } this.repository = repository ?? throw new ArgumentNullException(nameof(repository)); var callsFromRepository = this.repository.Load(); if (callsFromRepository == null) { var wrappedService = serviceFactory.Invoke(); this.Object = A.Fake <TService>(); this.recordingRule = new RecordingRule(wrappedService); Fake.GetFakeManager(this.Object).AddRuleFirst(this.recordingRule); } else { this.Object = A.Fake <TService>(); Fake.GetFakeManager(this.Object).AddRuleFirst(new PlaybackRule(new Queue <RecordedCall>(callsFromRepository))); } }
public static void SerializeVoidCall( string path, IRecordedCallRepository repository, IService realServiceWhileRecording, int voidMethodOutInteger, DateTime voidMethodRefDateTime, Guid nonVoidMethodResult) { "Given a file path" .x(() => path = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".xml")); "And a XmlFileRecordedCallRepository targeting that path" .x(() => repository = new XmlFileRecordedCallRepository(path)); "And a real service to wrap while recording" .x(() => { realServiceWhileRecording = A.Fake <IService>(); int i; DateTime dt = DateTime.MinValue; A.CallTo(() => realServiceWhileRecording.VoidMethod("firstCallKey", out i, ref dt)) .AssignsOutAndRefParameters(17, new DateTime(2017, 1, 24)); A.CallTo(() => realServiceWhileRecording.NonVoidMethod()) .Returns(new Guid("6c7d8912-802a-43c0-82a2-cb811058a9bd")); }); "When I use a self-initializing fake in recording mode" .x(() => { using (var fakeService = SelfInitializingFake <IService> .For(() => realServiceWhileRecording, repository)) { var fake = fakeService.Object; fake.VoidMethod("firstCallKey", out voidMethodOutInteger, ref voidMethodRefDateTime); nonVoidMethodResult = fake.NonVoidMethod(); } }); "And I use a self-initializing fake in playback mode" .x(() => { using (var playbackFakeService = SelfInitializingFake <IService> .For <IService>(UnusedFactory, repository)) { var fake = playbackFakeService.Object; int i; DateTime dt = DateTime.MinValue; fake.VoidMethod("blah", out i, ref dt); } }); "Then the recording fake forwards calls to the wrapped service" .x(() => { int i; #if BUG_ASSIGNING_REF_VALUE_CLEARS_INCOMING_VALUE DateTime dt = new DateTime(2017, 1, 24); #else DateTime dt = DateTime.MinValue; #endif A.CallTo(() => realServiceWhileRecording.VoidMethod(A <string> ._, out i, ref dt)) .MustHaveHappened(); A.CallTo(() => realServiceWhileRecording.NonVoidMethod()).MustHaveHappened(); }); "And the playback fake returns the recorded out and ref parameters and results" .x(() => { voidMethodOutInteger.Should().Be(17); voidMethodRefDateTime.Should().Be(new DateTime(2017, 1, 24)); nonVoidMethodResult.Should().Be(new Guid("6c7d8912-802a-43c0-82a2-cb811058a9bd")); }); }
public static void SerializeVoidCall( string path, IRecordedCallRepository repository, IService realServiceWhileRecording, int voidMethodOutInteger, DateTime voidMethodRefDateTime, IDictionary <string, Guid> nonVoidMethodResult) { "Given a file path" .x(() => path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())); "And a BinaryFileRecordedCallRepository targeting that path" .x(() => repository = new BinaryFileRecordedCallRepository(path)); "And a real service to wrap while recording" .x(() => { realServiceWhileRecording = A.Fake <IService>(); int i; DateTime dt = DateTime.MinValue; A.CallTo(() => realServiceWhileRecording.VoidMethod("firstCallKey", out i, ref dt)) .AssignsOutAndRefParameters(17, new DateTime(2017, 1, 24)); A.CallTo(() => realServiceWhileRecording.NonVoidMethod()) .Returns(new Dictionary <string, Guid> { ["key1"] = new Guid("6c7d8912-802a-43c0-82a2-cb811058a9bd"), }); }); "When I use a self-initializing fake in recording mode" .x(() => { using (var fakeService = SelfInitializingFake <IService> .For(() => realServiceWhileRecording, repository)) { var fake = fakeService.Object; fake.VoidMethod("firstCallKey", out voidMethodOutInteger, ref voidMethodRefDateTime); nonVoidMethodResult = fake.NonVoidMethod(); } }); "And I use a self-initializing fake in playback mode" .x(() => { using (var playbackFakeService = SelfInitializingFake <IService> .For <IService>(() => null, repository)) { var fake = playbackFakeService.Object; int i; DateTime dt = DateTime.MinValue; fake.VoidMethod("blah", out i, ref dt); } }); "Then the recording fake forwards calls to the wrapped service" .x(() => { int i; #if FAKEITEASY3 DateTime dt = new DateTime(2017, 1, 24); #else DateTime dt = DateTime.MinValue; #endif A.CallTo(() => realServiceWhileRecording.VoidMethod(A <string> ._, out i, ref dt)) .MustHaveHappened(); A.CallTo(() => realServiceWhileRecording.NonVoidMethod()).MustHaveHappened(); }); "And the playback fake returns the recorded out and ref parameters and results" .x(() => { voidMethodOutInteger.Should().Be(17); voidMethodRefDateTime.Should().Be(new DateTime(2017, 1, 24)); nonVoidMethodResult.Should() .HaveCount(1).And .ContainKey("key1") .WhichValue.Should().Be(new Guid("6c7d8912-802a-43c0-82a2-cb811058a9bd")); }); }