public async Task ExecuteAsync_WhenTransactionTimesOut_MustThrowException() { // Arrange TimeSpan transactionTimeOut = TimeSpan.FromMilliseconds(1); TimeSpan biggerTimeout = TimeSpan.FromMilliseconds(1000); string userName = $"test-user--{Guid.NewGuid():N}"; IIdentity identity = new GenericIdentity(userName); string[] roles = { $"role--{Guid.NewGuid():N}" }; IPrincipal flowInitiator = new GenericPrincipal(identity, roles); ITodoItemService todoItemService = testWebApplicationFactory.Services.GetRequiredService <ITodoItemService>(); ILoggerFactory loggerFactory = testWebApplicationFactory.Services.GetRequiredService <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger <ApplicationFlowServingTestingPurposes>(); string namePrefix = $"todo-item--{Guid.NewGuid():N}"; // This flow is expected to fail ITodoItemService localTodoItemService = todoItemService; async Task <object> FlowExpectedToFailAsync() { await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#1", IsComplete = false, Owner = flowInitiator }); await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#2", IsComplete = false, Owner = flowInitiator }); // Ensure this flow step will take more time to execute than the configured transaction timeout used // by the application flow. Task.Delay(biggerTimeout).Wait(); return(null); } var query = new TodoItemQuery { Owner = flowInitiator, NamePattern = $"{namePrefix}%" }; ApplicationFlowOptions applicationFlowOptions = testWebApplicationFactory.Services.GetRequiredService <ApplicationFlowOptions>(); // Ensure the application flow will use a very short timeout value for its transaction. applicationFlowOptions.TransactionOptions.Timeout = transactionTimeOut; var applicationFlow = new ApplicationFlowServingTestingPurposes(FlowExpectedToFailAsync, applicationFlowOptions, logger); // Act Func <Task> executeAsyncCall = async() => await applicationFlow.ExecuteAsync(input : null, flowInitiator); // Get a new instance of ITodoItemService service to ensure data will be fetched from // a new DbContext. todoItemService = testWebApplicationFactory.Services.GetRequiredService <ITodoItemService>(); IList <TodoItemInfo> list = await todoItemService.GetByQueryAsync(query); // Assert using (new AssertionScope()) { await executeAsyncCall .Should() .ThrowExactlyAsync <TransactionAbortedException>( "application flow must fail in case of transaction timeout"); list.Count.Should().Be(expected: 0, "no entities must be created in the event of a transaction timeout"); } }
public async Task ExecuteAsync_WhenOneFlowStepThrowsException_MustThrowException() { // Arrange string userName = $"test-user--{Guid.NewGuid():N}"; IIdentity identity = new GenericIdentity(userName); string[] roles = { $"role--{Guid.NewGuid():N}" }; IPrincipal flowInitiator = new GenericPrincipal(identity, roles); ITodoItemService todoItemService = testWebApplicationFactory.Services.GetRequiredService <ITodoItemService>(); ILoggerFactory loggerFactory = testWebApplicationFactory.Services.GetRequiredService <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger <ApplicationFlowServingTestingPurposes>(); string namePrefix = $"todo-item--{Guid.NewGuid():N}"; ITodoItemService localTodoItemService = todoItemService; // This flow is expected to fail since the service is unable to persist invalid models async Task <object> FlowExpectedToThrowExceptionAsync() { await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#1", Owner = flowInitiator }); await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#2", Owner = flowInitiator }); await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#3", Owner = flowInitiator }); return(null); } ApplicationFlowOptions applicationFlowOptions = testWebApplicationFactory.Services.GetRequiredService <ApplicationFlowOptions>(); var applicationFlow = new ApplicationFlowServingTestingPurposes(FlowExpectedToThrowExceptionAsync, applicationFlowOptions, logger); // Act Func <Task> executeAsyncCall = async() => await applicationFlow.ExecuteAsync(input : null, flowInitiator); // Assert using (new AssertionScope()) { await executeAsyncCall .Should() .ThrowExactlyAsync <ValidationException>("application flow must fail in case of an error"); var query = new TodoItemQuery { Owner = flowInitiator, NamePattern = $"{namePrefix}%" }; // Get a new instance of ITodoItemService service to ensure data will be fetched from // a new DbContext. todoItemService = testWebApplicationFactory.Services.GetRequiredService <ITodoItemService>(); IList <TodoItemInfo> list = await todoItemService.GetByQueryAsync(query); list.Count.Should().Be(expected: 0, "the application flow failed to persist todo items"); } }
public async Task ExecuteAsync_WhenAllStepsSucceeds_MustSucceed() { // Arrange string userName = $"test-user--{Guid.NewGuid():N}"; IIdentity identity = new GenericIdentity(userName); string[] roles = { $"role--{Guid.NewGuid():N}" }; IPrincipal flowInitiator = new GenericPrincipal(identity, roles); ITodoItemService todoItemService = testWebApplicationFactory.Services.GetRequiredService <ITodoItemService>(); ILoggerFactory loggerFactory = testWebApplicationFactory.Services.GetRequiredService <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger <ApplicationFlowServingTestingPurposes>(); string namePrefix = $"todo-item--{Guid.NewGuid():N}"; // This flow is expected to succeed since the service is persisting valid models ITodoItemService localTodoItemService = todoItemService; async Task <object> FlowExpectedToSucceedAsync() { await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#1", IsComplete = false, Owner = flowInitiator }); await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#2", IsComplete = false, Owner = flowInitiator }); await localTodoItemService.AddAsync(new NewTodoItemInfo { Name = $"{namePrefix}--#3", IsComplete = false, Owner = flowInitiator }); return(null); } ApplicationFlowOptions applicationFlowOptions = testWebApplicationFactory.Services.GetRequiredService <ApplicationFlowOptions>(); var applicationFlow = new ApplicationFlowServingTestingPurposes(FlowExpectedToSucceedAsync, applicationFlowOptions, logger); // Act await applicationFlow.ExecuteAsync(input : null, flowInitiator); // Assert var query = new TodoItemQuery { Owner = flowInitiator, NamePattern = $"{namePrefix}%" }; // Get a new instance of ITodoItemService service to ensure data will be fetched from // a new DbContext. todoItemService = testWebApplicationFactory.Services.GetRequiredService <ITodoItemService>(); IList <TodoItemInfo> list = await todoItemService.GetByQueryAsync(query); list.Count.Should().Be(expected: 3, "several todo items have been previously created"); }