public Facts(ITestOutputHelper output)
            {
                CloudBlobClient    = new Mock <ICloudBlobClient>();
                CloudBlobContainer = new Mock <ICloudBlobContainer>();
                CloudBlob          = new Mock <ISimpleCloudBlob>();
                Options            = new Mock <IOptionsSnapshot <AzureSearchJobConfiguration> >();
                TelemetryService   = new Mock <IAzureSearchTelemetryService>();
                Logger             = output.GetLogger <PopularityTransferDataClient>();
                Config             = new AzureSearchJobConfiguration
                {
                    StorageContainer = "unit-test-container",
                };

                ETag            = "\"some-etag\"";
                AccessCondition = new Mock <IAccessCondition>();
                StringCache     = new StringCache();
                ReplaceLatestIndexedPopularityTransfersDurationMetric = new Mock <IDisposable>();

                Options
                .Setup(x => x.Value)
                .Returns(() => Config);
                CloudBlobClient
                .Setup(x => x.GetContainerReference(It.IsAny <string>()))
                .Returns(() => CloudBlobContainer.Object);
                CloudBlobContainer
                .Setup(x => x.GetBlobReference(It.IsAny <string>()))
                .Returns(() => CloudBlob.Object)
                .Callback <string>(x => BlobNames.Add(x));
                CloudBlob
                .Setup(x => x.ETag)
                .Returns(ETag);
                CloudBlob
                .Setup(x => x.OpenWriteAsync(It.IsAny <AccessCondition>()))
                .ReturnsAsync(() => new RecordingStream(bytes =>
                {
                    SavedBytes.Add(bytes);
                    SavedStrings.Add(Encoding.UTF8.GetString(bytes));
                }));
                CloudBlob
                .Setup(x => x.Properties)
                .Returns(new CloudBlockBlob(new Uri("https://example/blob")).Properties);

                TelemetryService
                .Setup(x => x.TrackReplaceLatestIndexedPopularityTransfers(It.IsAny <int>()))
                .Returns(ReplaceLatestIndexedPopularityTransfersDurationMetric.Object);

                Target = new PopularityTransferDataClient(
                    CloudBlobClient.Object,
                    Options.Object,
                    TelemetryService.Object,
                    Logger);
            }
            public Facts(ITestOutputHelper output)
            {
                DatabaseOwnerFetcher     = new Mock <IDatabaseAuxiliaryDataFetcher>();
                OwnerDataClient          = new Mock <IOwnerDataClient>();
                OwnerSetComparer         = new Mock <IDataSetComparer>();
                SearchDocumentBuilder    = new Mock <ISearchDocumentBuilder>();
                SearchIndexActionBuilder = new Mock <ISearchIndexActionBuilder>();
                Pusher           = new Mock <IBatchPusher>();
                Options          = new Mock <IOptionsSnapshot <AzureSearchJobConfiguration> >();
                TelemetryService = new Mock <IAzureSearchTelemetryService>();
                Logger           = output.GetLogger <UpdateOwnersCommand>();

                Configuration = new AzureSearchJobConfiguration
                {
                    MaxConcurrentBatches = 1,
                };
                DatabaseResult = new SortedDictionary <string, SortedSet <string> >();
                StorageResult  = new ResultAndAccessCondition <SortedDictionary <string, SortedSet <string> > >(
                    new SortedDictionary <string, SortedSet <string> >(),
                    new Mock <IAccessCondition>().Object);
                Changes      = new SortedDictionary <string, string[]>();
                IndexActions = new IndexActions(
                    new List <IndexAction <KeyedDocument> > {
                    IndexAction.Merge(new KeyedDocument())
                },
                    new List <IndexAction <KeyedDocument> > {
                    IndexAction.Merge(new KeyedDocument())
                },
                    new ResultAndAccessCondition <VersionListData>(
                        new VersionListData(new Dictionary <string, VersionPropertiesData>()),
                        new Mock <IAccessCondition>().Object));

                Pusher.SetReturnsDefault(Task.FromResult(new BatchPusherResult()));
                Options
                .Setup(x => x.Value)
                .Returns(() => Configuration);
                DatabaseOwnerFetcher
                .Setup(x => x.GetPackageIdToOwnersAsync())
                .ReturnsAsync(() => DatabaseResult);
                OwnerDataClient
                .Setup(x => x.ReadLatestIndexedAsync())
                .ReturnsAsync(() => StorageResult);
                OwnerSetComparer
                .Setup(x => x.CompareOwners(
                           It.IsAny <SortedDictionary <string, SortedSet <string> > >(),
                           It.IsAny <SortedDictionary <string, SortedSet <string> > >()))
                .Returns(() => Changes);
                SearchIndexActionBuilder
                .Setup(x => x.UpdateAsync(It.IsAny <string>(), It.IsAny <Func <SearchFilters, KeyedDocument> >()))
                .ReturnsAsync(() => IndexActions);

                Target = new UpdateOwnersCommand(
                    DatabaseOwnerFetcher.Object,
                    OwnerDataClient.Object,
                    OwnerSetComparer.Object,
                    SearchDocumentBuilder.Object,
                    SearchIndexActionBuilder.Object,
                    () => Pusher.Object,
                    Options.Object,
                    TelemetryService.Object,
                    Logger);
            }