private void DidReceiveCall(ILogger mockLogger, LogLevel severity, Exception exception) { mockLogger.Received().Log(Arg.Is<LogEntry>(x => x.Severity == severity && x.Message == exception.Message && x.Exception == exception)); }
public async Task GetUserByUserId_GivenUserFoundInCacheButUpdatingReturnsBadRequest_ReturnsInternalServerError() { //Arrange User user = new User { Username = Username, HasConfirmedSkills = false, Name = Name, UserId = UserId, }; UserCreateModel userCreateModel = new UserCreateModel() { Name = Name, Username = Username }; ILogger logger = CreateLogger(); ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <User>(Arg.Any <string>()) .Returns(user); IUserRepository userRepository = CreateUserRepository(); userRepository .SaveUser(Arg.Is(user)) .Returns(HttpStatusCode.BadRequest); IValidator <UserCreateModel> validator = CreateUserCreateModelValidator(); validator .ValidateAsync(Arg.Any <UserCreateModel>()) .Returns(new ValidationResult()); UserService userService = CreateUserService(userRepository, logger, cacheProvider, validator); //Act IActionResult result = await userService.ConfirmSkills(UserId, userCreateModel); //Assert result .Should() .BeOfType <InternalServerErrorResult>() .Which .Value .Should() .Be("Failed to confirm skills"); logger .Received(1) .Error(Arg.Is("Failed to confirm skills in database with status code: BadRequest")); }
public async Task ProcessJobCompletion_JobHasParentThatIsCompleted_ThenNotificationSent() { // Arrange string parentJobId = "parent123"; string jobId = "child123"; Job job = new Job { Id = jobId, ParentJobId = parentJobId, CompletionStatus = CompletionStatus.Succeeded, RunningStatus = RunningStatus.Completed }; Job parentJob = new Job { Id = parentJobId, RunningStatus = RunningStatus.InProgress }; ILogger logger = CreateLogger(); IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .GetJobById(Arg.Is(parentJobId)) .Returns(parentJob); jobRepository .GetChildJobsForParent(Arg.Is(parentJobId)) .Returns(new List <Job> { job }); INotificationService notificationService = CreateNotificationsService(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository, logger: logger, notificationService: notificationService); JobNotification jobNotification = new JobNotification { JobId = jobId, RunningStatus = RunningStatus.Completed }; string json = JsonConvert.SerializeObject(jobNotification); Message message = new Message(Encoding.UTF8.GetBytes(json)); message.UserProperties["jobId"] = jobId; // Act await jobManagementService.ProcessJobNotification(message); // Assert await notificationService .Received(1) .SendNotification(Arg.Is <JobNotification>(n => n.JobId == parentJobId && n.RunningStatus == RunningStatus.Completed)); logger .Received(1) .Information(Arg.Is("Parent Job {ParentJobId} of Completed Job {JobId} has been completed because all child jobs are now complete"), Arg.Is(job.ParentJobId), Arg.Is(jobId)); }
public async Task ReIndex_GivenIndexingThrowsException_ReturnsInternalServerError() { //Arrange IEnumerable <SpecificationSearchModel> specifications = new[] { new SpecificationSearchModel { Id = SpecificationId, Name = SpecificationName, FundingStreams = new List <Reference> { new Reference("fs-id", "fs-name") }, FundingPeriod = new Reference("18/19", "2018/19"), UpdatedAt = DateTime.Now } }; // ISearchRepository<SpecificationIndex> searchRepository = CreateSearchRepository(); // searchRepository // .When(x => x.Index(Arg.Any<List<SpecificationIndex>>())) // .Do(x => { throw new Exception(); }); _specificationIndexer .When(_ => _.Index(Arg.Any <IEnumerable <SpecificationSearchModel> >())) .Throw(new Exception()); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationsByRawQuery <SpecificationSearchModel>(Arg.Any <CosmosDbQuery>()) .Returns(specifications); ILogger logger = CreateLogger(); ISpecificationsService service = CreateService(logs: logger, specificationsRepository: specificationsRepository); //Act IActionResult result = await service.ReIndex(); //Assert logger .Received(1) .Error(Arg.Any <Exception>(), Arg.Is("Failed re-indexing specifications")); result .Should() .BeOfType <StatusCodeResult>(); StatusCodeResult statusCodeResult = result as StatusCodeResult; statusCodeResult .StatusCode .Should() .Be(500); }
public void IsLoginOK_WhenCalled_WritesToLog_AAA() { ILogger fake = Substitute.For <ILogger>(); LoginManagerWithMock lm = new LoginManagerWithMock(fake); lm.IsLoginOK("", ""); fake.Received().Write(Arg.Is <string>(s => s.Contains("a"))); }
public void GetById_ShouldLogAppropriateMessage_WhenCustomerExists() { // Arrange var RxUserId = Guid.NewGuid(); var RxUserFirst = "FirstName"; var RxUserLast = "LastName"; var RxUserdto = new RxUserModel { Id = RxUserId.ToString(), FirstName = RxUserFirst, LastName = RxUserLast }; _RxUserRepository.GetById(RxUserId).Returns(RxUserdto); // Act var RxUser = _sut.GetById(RxUserId); // Assert _logger.Received(1).LogInformation("Found a user"); _logger.DidNotReceive().LogInformation("No user found!"); }
public void Get_Logs_The_Number() { // NSubstitute ILogger logger = Substitute.For <ILogger>(); var fizzBuzzer = new FizzBuzzer(logger); fizzBuzzer.Get(42); logger.Received().Log("43"); }
public void Analyze_NameToShort_CallsLogger() { ILogger fakeLogger = Substitute.For <ILogger>(); LogAnalyzer analyzer = new LogAnalyzer(fakeLogger); analyzer.Analyze("a.txt"); fakeLogger.Received().LogError("Filename too short:a.txt"); }
public async Task Given_AddressServiceFails_When_GetAddressCityGroups_Then_LogMessage() { var serviceExceptionMessage = "some error"; _addressService.GetAddressCityGroups().Throws(new Exception(serviceExceptionMessage)); var result = await _sut.GetAddressCityGroups(); _logger.Received().LogError(serviceExceptionMessage); }
public void Analyze_ToShortFileName_CallLogger() { ILogger logger = Substitute.For <ILogger>(); LogAnalyzer analyzer = new LogAnalyzer(logger); analyzer.MinNameLength = 6; analyzer.Analyze("a.txt"); logger.Received().LogError("Nazwa pliku jest za krótka: a.txt"); }
public void Analyze_TooShortFileName_CallLogger() { ILogger logger = Substitute.For <ILogger>(); LogAnalyzer_ILogger analyzer = new LogAnalyzer_ILogger(logger); analyzer.MinNameLength = 6; analyzer.Analyze("a.txt"); logger.Received().LogError("Filename too short: a.txt"); }
public async Task GetPolicyByName_GivenSpecificationExistsAndPolicyExists_ReturnsSuccess() { //Arrange Specification spec = new Specification { Current = new SpecificationVersion() { Policies = new[] { new Policy { Name = PolicyName } }, }, }; PolicyGetModel model = new PolicyGetModel { SpecificationId = SpecificationId, Name = PolicyName }; string json = JsonConvert.SerializeObject(model); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpRequest request = Substitute.For <HttpRequest>(); request .Body .Returns(stream); ILogger logger = CreateLogger(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(spec); SpecificationsService service = CreateService(specificationsRepository: specificationsRepository, logs: logger); //Act IActionResult result = await service.GetPolicyByName(request); //Assert result .Should() .BeOfType <OkObjectResult>(); logger .Received(1) .Information(Arg.Is($"A policy was found for specification id {SpecificationId} and name {PolicyName}")); }
public async Task CheckAndProcessTimedOutJobs_GivenNonCompletedJobsAndHasTimeOutButFailedToUpdate_LogsError() { //Arrange Job job = new Job { Id = "job-id-1", JobDefinitionId = "job-def-2", Created = DateTimeOffset.Now.AddHours(-13) }; IEnumerable <Job> nonCompletedJobs = new[] { job }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetNonCompletedJobs() .Returns(nonCompletedJobs); jobRepository .GetLatestJobBySpecificationIdAndDefinitionId(Arg.Any <string>(), Arg.Any <string>()) .Returns(job); jobRepository .UpdateJob(Arg.Any <Job>()) .Returns(HttpStatusCode.BadRequest); IEnumerable <JobDefinition> jobDefinitions = new[] { new JobDefinition { Id = "job-def-1", Timeout = TimeSpan.FromHours(12) }, new JobDefinition { Id = "job-def-2", Timeout = TimeSpan.FromHours(12) } }; IJobDefinitionsService jobDefinitionsService = CreateJobDefinitionsService(); jobDefinitionsService .GetAllJobDefinitions() .Returns(jobDefinitions); ILogger logger = CreateLogger(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository, logger: logger, jobDefinitionsService: jobDefinitionsService); //Act await jobManagementService.CheckAndProcessTimedOutJobs(); //Assert logger .Received(1) .Error(Arg.Is("Failed to update timeout job, Id: 'job-id-1' with status code 400")); }
public void ExecuteAsync_Should_CatchOperationCanceledException_And_WriteInfoToLog_When_CancellationTokenWasCanceled() { var cts = new CancellationTokenSource(); cts.Cancel(); Expect(() => _handler.ExecuteAsync(_fileInfo, cts.Token), Throws.Nothing); _logger.Received(1).Info(Arg.Any <string>(), Arg.Any <object[]>()); }
async public Task SaveFundingStream_GivenValidYamlButFailedToSaveToDatabase_ReturnsStatusCode() { //Arrange string yaml = CreateRawFundingStream(); byte[] byteArray = Encoding.UTF8.GetBytes(yaml); MemoryStream stream = new MemoryStream(byteArray); IHeaderDictionary headerDictionary = new HeaderDictionary { { "yaml-file", new StringValues(yamlFile) } }; HttpRequest request = Substitute.For <HttpRequest>(); request .Headers .Returns(headerDictionary); request .Body .Returns(stream); ILogger logger = CreateLogger(); HttpStatusCode failedCode = HttpStatusCode.BadGateway; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .SaveFundingStream(Arg.Any <FundingStream>()) .Returns(failedCode); IFundingService service = CreateService(logger: logger, specificationsRepository: specificationsRepository); //Act IActionResult result = await service.SaveFundingStream(request); //Assert result .Should() .BeOfType <StatusCodeResult>(); StatusCodeResult statusCodeResult = (StatusCodeResult)result; statusCodeResult .StatusCode .Should() .Be(502); logger .Received(1) .Error(Arg.Is($"Failed to save yaml file: {yamlFile} to cosmos db with status 502")); }
async public Task SaveFundingConfiguration_GivenValidConfigurationButFailedToSaveToDatabase_ReturnsStatusCode(string fundingStreamId, string fundingPeriodId) { //Arrange FundingStream fundingStream = new FundingStream { Id = fundingStreamId }; FundingPeriod fundingPeriod = new FundingPeriod { Id = fundingPeriodId }; ILogger logger = CreateLogger(); HttpStatusCode statusCode = HttpStatusCode.BadRequest; IPolicyRepository policyRepository = CreatePolicyRepository(); policyRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); policyRepository .GetFundingPeriodById(Arg.Is(fundingPeriodId)) .Returns(fundingPeriod); policyRepository .SaveFundingConfiguration(Arg.Is <FundingConfiguration>(x => x.FundingStreamId == fundingStreamId && x.FundingPeriodId == fundingPeriodId)) .Returns(statusCode); FundingConfigurationService fundingConfigurationsService = CreateFundingConfigurationService(logger: logger, policyRepository: policyRepository); FundingConfigurationViewModel fundingConfigurationViewModel = CreateConfigurationModel(); //Act IActionResult result = await fundingConfigurationsService.SaveFundingConfiguration("Action", "Controller", fundingConfigurationViewModel, fundingStreamId, fundingPeriodId); //Assert result .Should() .BeOfType <InternalServerErrorResult>(); InternalServerErrorResult statusCodeResult = (InternalServerErrorResult)result; statusCodeResult .StatusCode .Should() .Be(500); logger .Received(1) .Error(Arg.Is($"Failed to save configuration file for funding stream id: {fundingStreamId} and period id: {fundingPeriodId} to cosmos db with status 400")); }
public async Task InvokeAsync_LogsRequest(string method, string path) { ILogger logger = Substitute.For <ILogger>(); var apiBuilder = new ApiBuilder(Substitute.For <ISimulation>()); var apiSettings = new ApiSimulatorSettings(apiBuilder); var context = new DefaultHttpContext(); context.Request.Method = method; context.Request.Path = path; var middleware = new ApiSimulatorOwinMiddleware(apiSettings, logger, _ => { }); await middleware.InvokeAsync(context, _ => Task.CompletedTask); Received.InOrder(() => { logger.Received(1).Log(LogLevel.Debug, 0, Arg.Is <FormattedLogValues>(value => value.ToString() == $"Request \"{method} {path}\" started"), null, Arg.Any <Func <object, Exception, string> >()); logger.Received(1).Log(LogLevel.Debug, 0, Arg.Is <FormattedLogValues>(value => value.ToString() == $"Request \"{method} {path}\" completed"), null, Arg.Any <Func <object, Exception, string> >()); }); }
public void Analyze_TooShortFileName_CallLoggerArgMatchers() { ILogger logger = Substitute.For <ILogger>(); LogAnalyzer analyzer = new LogAnalyzer(logger); analyzer.MinNameLength = 6; analyzer.Analyze("a.txt"); logger.Received().LogError(Arg.Is <string>(s => s.Contains("too short"))); }
public void WhenMultipleHandlersAreAdded_ShouldCallAllHandlersAndBaseLogger() { AmbientLogService sut = new AmbientLogService(); string message = Guid.NewGuid().ToString(); sut.Verbose(message); _loggerMock.Received(1).Verbose(message); _handler1.Received(1).Verbose(message); _handler2.Received(1).Verbose(message); }
public async Task GetSpecificationsSelectedForFundingByPeriod_GivenSpecificationWasNotFound_ReturnsNotFound() { //Arrange SpecificationVersion sv1 = new SpecificationVersion { SpecificationId = "spec1", FundingPeriod = new Reference { Id = "18/19", Name = "18/19" } }; SpecificationVersion sv2 = new SpecificationVersion { SpecificationId = "spec2", FundingPeriod = new Reference { Id = "17/18", Name = "17/18" } }; Specification spec1 = new Specification { Id = "spec1", IsSelectedForFunding = true, Current = sv1 }; Specification spec2 = new Specification { Id = "spec2", IsSelectedForFunding = true, Current = sv2 }; IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "fundingPeriodId", new StringValues(FundingPeriodId) } }); HttpRequest request = Substitute.For <HttpRequest>(); request .Query .Returns(queryStringValues); ILogger logger = CreateLogger(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationsByQuery(Arg.Any <Expression <Func <Specification, bool> > >()) .Returns((Enumerable.Empty <Specification>())); SpecificationsService service = CreateService(specificationsRepository: specificationsRepository, logs: logger); //Act IActionResult result = await service.GetSpecificationsSelectedForFundingByPeriod(request); //Assert result .Should() .BeOfType <NotFoundResult>(); logger .Received(1) .Information(Arg.Is($"Specification was not found for funding period: {FundingPeriodId}")); }
public void InitializeLogsWatchdogThreadStart() { // given mockContext.IsShutdownRequested.ReturnsForAnyArgs(x => true).AndDoes(x => threadEvent.Set()); var target = CreateWatchdog(); // when target.Initialize(); threadEvent.WaitOne(1000); // wait for thread // then mockLogger.Received(1) .Debug($"{typeof(SessionWatchdog).Name} Initialize() - thread started"); _ = mockContext.Received(1).IsShutdownRequested; mockContext.Received(0).Execute(); // cleanup target.Shutdown(); }
public async Task SaveDataset_GivenViewModelIsNotNullButResponseContainsModelErrors_ReturnsBadRequest() { // Arrange ValidatedApiResponse <NewDatasetVersionResponseModel> response = new ValidatedApiResponse <NewDatasetVersionResponseModel>(HttpStatusCode.BadRequest) { ModelState = new Dictionary <string, IEnumerable <string> > { { "Name", new[] { "Invalid name" } } } }; CreateDatasetViewModel viewModel = new CreateDatasetViewModel { Description = "Description", Filename = "Filename.xlsx", Name = "Name", DataDefinitionId = "0123456789", FundingStreamId = "DSG" }; _apiClient .CreateNewDataset(Arg.Any <CreateNewDatasetModel>()) .Returns(response); // Act IActionResult result = await _controller.SaveDataset(viewModel); // Assert _logger .Received(1) .Warning(Arg.Is("Invalid model provided")); result .Should() .BeOfType <BadRequestObjectResult>(); }
public void Analyze_TooShortFileName_CallLogger() { // 创建模拟对象,用于测试结尾的断言 ILogger logger = Substitute.For <ILogger>(); LogAnalyzer analyzer = new LogAnalyzer(logger); analyzer.MinNameLength = 6; analyzer.Analyze("a.txt"); // 使用NSub API设置预期字符串 logger.Received().LogError("Filename too short : a.txt"); }
public void ProcessCompactionStats_EmptyDump() { ILogger logger = Substitute.For <ILogger>(); string testDump = string.Empty; new DbMetricsUpdater("Test", null, null, null, logger).ProcessCompactionStats(testDump); Assert.AreEqual(0, Metrics.DbStats.Count); logger.Received().Warn("No RocksDB compaction stats available for Test databse."); }
public async Task GetFundingTemplate_GivenTemplateDoesExistInBlobStorageButIsEmpty_ReturnsInternalServerError() { //Arrange const string fundingStreamId = "PES"; const string templateVersion = "1.2"; const string fundingPeriodId = "AY-2020"; string cacheKey = $"{CacheKeys.FundingTemplatePrefix}{fundingStreamId}-{fundingPeriodId}-{templateVersion}"; string blobName = $"{fundingStreamId}/{fundingPeriodId}/{templateVersion}.json"; string template = string.Empty; ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <string>(Arg.Is(cacheKey)) .Returns((string)null); IFundingTemplateRepository fundingTemplateRepository = CreateFundingTemplateRepository(); fundingTemplateRepository .TemplateVersionExists(Arg.Is(blobName)) .Returns(true); fundingTemplateRepository .GetFundingTemplateVersion(Arg.Is(blobName)) .Returns(template); ILogger logger = CreateLogger(); FundingTemplateService fundingTemplateService = CreateFundingTemplateService( logger, cacheProvider: cacheProvider, fundingTemplateRepository: fundingTemplateRepository); //Act ActionResult <string> result = await fundingTemplateService.GetFundingTemplateSourceFile(fundingStreamId, fundingPeriodId, templateVersion); //Assert result .Result .Should() .BeAssignableTo <InternalServerErrorResult>() .Which .Value .Should() .Be($"Failed to retreive blob contents for funding stream id '{fundingStreamId}', funding period id '{fundingPeriodId}' and funding template version '{templateVersion}'"); logger .Received(1) .Error($"Empty template returned from blob storage for blob name '{blobName}'"); }
public async Task GetFundingTemplate_GivenFetechingBlobFails_ReturnsInternalServerError() { //Arrange const string fundingStreamId = "PES"; const string templateVersion = "1.2"; const string fundingPeriodId = "AY-2020"; string cacheKey = $"{CacheKeys.FundingTemplatePrefix}{fundingStreamId}-{fundingPeriodId}-{templateVersion}"; string blobName = $"{fundingStreamId}/{fundingPeriodId}/{templateVersion}.json"; string template = string.Empty; ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <string>(Arg.Is(cacheKey)) .Returns((string)null); IFundingTemplateRepository fundingTemplateRepository = CreateFundingTemplateRepository(); fundingTemplateRepository .TemplateVersionExists(Arg.Is(blobName)) .Returns(true); fundingTemplateRepository .When(x => x.GetFundingTemplateVersion(Arg.Is(blobName))) .Do(x => { throw new Exception(); }); ILogger logger = CreateLogger(); FundingTemplateService fundingTemplateService = CreateFundingTemplateService( logger, cacheProvider: cacheProvider, fundingTemplateRepository: fundingTemplateRepository); //Act ActionResult <string> result = await fundingTemplateService.GetFundingTemplateSourceFile(fundingStreamId, fundingPeriodId, templateVersion); //Assert result .Result .Should() .BeAssignableTo <InternalServerErrorResult>() .Which .Value .Should() .Be($"Error occurred fetching funding template for funding stream id '{fundingStreamId}', funding period id '{fundingPeriodId}' and version '{templateVersion}'"); logger .Received(1) .Error(Arg.Any <Exception>(), $"Failed to fetch funding template '{blobName}' from blob storage"); }
public void Analyze_TooShortFileName_UseNSub_CallLogger() { ILogger logger = Substitute.For <ILogger>(); LogAnalyzer analyzer = new LogAnalyzer(logger); analyzer.MinNameLength = 6; analyzer.Analyze("a.txt"); //使用NSub的API设置预期字符串,Received()这个方法在什么对象上调用,就会返回和这个对象同样类型的对象,但实际上是在声明断言对象。 //如果不加Received(),伪对象就会认为这个调用是产品代码发出的。 //使用Received(),就是在询问它后面的这个LogError是否调用过。 logger.Received().LogError("Filename too short: a.txt"); }
public async Task GetVehicles_ExceptionThrown_ShouldLog( Exception exception, [Frozen] ILogger <VehiclesController> logger, [Frozen] IVehicleService vehicleService, VehiclesController sut) { vehicleService.GetAllAsync().Throws(exception); await sut.GetVehicles(); logger.Received().LogError(exception.ToString()); }
public void EmptyFileName() { _handler.Handle(string.Empty); // Call to Upload. _logger.Received(1).LogExec(Arg.Any <Expression <Func <bool> > >()); // Error logging. _logger.Received(1).LogInfo(FileUploadHandler.EmptyFileNameErrMsg); Assert.That(_handler.IsHandled, Is.False); }
public void ExecuteEvictionLogsAMessageOnceAndReturnsIfStrategyIsDisabled() { // given var configuration = new BeaconCacheConfiguration(0L, 1000L, 2000L); var target = new TimeEvictionStrategy(mockLogger, mockBeaconCache, configuration, mockTimingProvider, isShutdownFunc); mockLogger.IsInfoEnabled.Returns(true); // when executing the first time target.Execute(); // then var tmp = mockLogger.Received(1).IsInfoEnabled; mockLogger.ReceivedWithAnyArgs(1).Info(string.Empty); mockBeaconCache.DidNotReceiveWithAnyArgs().EvictRecordsByAge(0, 0L); // and when executing a second time mockLogger.ClearReceivedCalls(); target.Execute(); // then tmp = mockLogger.DidNotReceive().IsInfoEnabled; mockLogger.DidNotReceiveWithAnyArgs().Info(string.Empty); mockBeaconCache.DidNotReceiveWithAnyArgs().EvictRecordsByAge(0, 0L); }
public void ReturnsErrorMessageWhenSpecificationPublishStatusIsNotApproved() { // Arrange string specificationId = "specId01"; SpecificationSummary specificationSummary = new SpecificationSummary { Id = specificationId, ApprovalStatus = PublishStatus.Archived }; string errorMessage = "Specification failed refresh prerequisite check. Reason: must be approved"; // Act Func <Task> invocation = () => WhenThePreRequisitesAreChecked(specificationSummary, Enumerable.Empty <PublishedProvider>(), Enumerable.Empty <Provider>()); // Assert invocation .Should() .Throw <JobPrereqFailedException>() .Where(_ => _.Message == $"Specification with id: '{specificationSummary.Id} has prerequisites which aren't complete."); _logger .Received() .Error(errorMessage); }
private void DidReceiveCall(ILogger mockLogger, LogLevel severity, string message) { mockLogger.Received().Log(Arg.Is<LogEntry>(x => x.Severity == severity && x.Message == message)); }