public async Task Handle__CreateNewOrderIsFail__SendMethodOfINotifierWasNotCalled() { // Arrange var notifier = Substitute.For <INotifier>(); var dbContext = Substitute.For <OrderContext>(); var appSettings = AppSettingsFake.Generate(); var commandRequest = GenerateCommandRequest(); #region DbContextFactory var dbContextFactory = Substitute.For <IDbContextFactory <OrderContext> >(); dbContextFactory.Create(appSettings.ConnectionStrings.OrdersDb).Returns(dbContext); #endregion var handler = CreateTestedComponent(appSettings, dbContextFactory, notifier); #region CreateNewOrderCommand var createNewOrderCommand = Substitute.For <CreateNewOrderCommand>(dbContext); createNewOrderCommand.Execute(Arg.Any <CreateNewOrderCommand.Context>()) .Returns(Outcomes.Failure <Order>().WithMessage("test-error")); var createNewOrderCommandFactory = Substitute.For <CreateNewOrderCommand.Factory>(); createNewOrderCommandFactory.Create(dbContext).Returns(createNewOrderCommand); handler.SetCreateNewOrderCommandFactory(createNewOrderCommandFactory); #endregion // Act await handler.Handle(commandRequest, CancellationToken.None); // Assert notifier.Received(0).Send(Arg.Any <Notification>()); }
public async Task Handle__DriverExistInStorage__ReturnSuccess() { // Arrange var orderId = _faker.Random.Int(min: 0); var driverId = _faker.Random.Int(min: 0); var driver = new Driver() { Id = driverId, FullName = _faker.Person.FullName, Phone = _faker.Phone.PhoneNumber("+7 (9##) ###-##-##") }; var appSettings = AppSettingsFake.Generate(); #region IDbExecutor var dbExecutor = Substitute.For <IDbExecutor>(); dbExecutor.Query <Driver>(Arg.Any <string>()).Returns(new List <Driver>() { driver }); // NOTE: здесь надо быть осторожным, потому что если у нас будет несколько вызовов Execute внутри // тестируемого компонента, то т.к. стоит Arg.Any<T>, то будут переопределены все вызовы dbExecutor.Execute(Arg.Any <string>()); #endregion #region IDbExecutorFactory var dbExecutorFactory = Substitute.For <IDbExecutorFactory>(); dbExecutorFactory.Create(appSettings.ConnectionStrings.OrdersDb).Returns(dbExecutor); #endregion var handler = CreateTestedComponent(appSettings, dbExecutorFactory); var request = new SetDriverForOrderCommandRequest() { OrderId = orderId, DriverId = driverId }; // Act var result = await handler.Handle(request, CancellationToken.None); // Assert Assert.True(result.Success); }
public async Task Handle__CreateNewOrderIsFail__ReturnFailure_v2() { // Arrange var errorMessage = $"test-error: {_faker.Random.Words()}"; var notifier = Substitute.For <INotifier>(); var dbContext = Substitute.For <OrderContext>(); var appSettings = AppSettingsFake.Generate(); #region DbContextFactory var dbContextFactory = Substitute.For <IDbContextFactory <OrderContext> >(); dbContextFactory.Create(appSettings.ConnectionStrings.OrdersDb).Returns(dbContext); #endregion var handler = CreateTestedComponent(appSettings, dbContextFactory, notifier); #region CreateNewOrderCommand // Минус: немало кода (минус весьма сомнительный, потому что это в нашем примере добавление заказа в БД простое) // Плюс: // 1) изоляция от логики добавления нового заказа в БД // 2) соответственно, отсутствует необходимость дублирования этой логики // ВАЖНО: нас не интересует содержимое, нас интересует РЕЗУЛЬТАТ команды создания нового заказа, // т.к. от этого результата зависит поведение бизнес-компонента (если fail - выйти; если success - двигаемся дальше) var createNewOrderCommand = Substitute.For <CreateNewOrderCommand>(dbContext); createNewOrderCommand.Execute(Arg.Any <CreateNewOrderCommand.Context>()) // Задаем нужный нам результат .Returns(Outcomes.Failure <Order>().WithMessage(errorMessage)); var createNewOrderCommandFactory = Substitute.For <CreateNewOrderCommand.Factory>(); createNewOrderCommandFactory.Create(dbContext).Returns(createNewOrderCommand); handler.SetCreateNewOrderCommandFactory(createNewOrderCommandFactory); #endregion var commandRequest = GenerateCommandRequest(); // Act var result = await handler.Handle(commandRequest, CancellationToken.None); // Assert Assert.True(result.Failure); Assert.Contains(errorMessage, result.ToMultiLine()); }
public FinishOrderCommandHandlerV2Tests() { var orderId = _faker.Random.Int(min: 0); _finishDateTime = _faker.Date.Recent(); _order = new Order() { Id = orderId, FinishDateTime = null, Status = "" }; var orders = new List <Order>() { _order }; var ordersAsQueryable = orders.AsQueryable(); var dbContext = Substitute.For <OrderContext>(); var appSettings = AppSettingsFake.Generate(); #region DbContext var ordersDbSet = Substitute.For <DbSet <Order>, IQueryable <Order> >(); ((IQueryable <Order>)ordersDbSet).Provider.Returns(ordersAsQueryable.Provider); ((IQueryable <Order>)ordersDbSet).Expression.Returns(ordersAsQueryable.Expression); ((IQueryable <Order>)ordersDbSet).ElementType.Returns(ordersAsQueryable.ElementType); ((IQueryable <Order>)ordersDbSet).GetEnumerator().Returns(ordersAsQueryable.GetEnumerator()); dbContext.Orders.Returns(ordersDbSet); dbContext.SaveChanges().Returns(1); #endregion #region DbContextFactory var dbContextFactory = Substitute.For <IDbContextFactory <OrderContext> >(); dbContextFactory.Create(appSettings.ConnectionStrings.OrdersDb).Returns(dbContext); #endregion _handler = CreateTestedComponent(appSettings, dbContextFactory); _commandRequest = new FinishOrderCommandRequestV2() { OrderId = orderId, FinishDateTime = _finishDateTime }; }
public async Task Handle__DriverNotFoundInStorage__ReturnFailureWithValidErrorMessage() { // Arrange var orderId = _faker.Random.Int(min: 0); var driverId = _faker.Random.Int(min: 0); var appSettings = AppSettingsFake.Generate(); #region IDbExecutor var dbExecutor = Substitute.For <IDbExecutor>(); // 1 способ: dbExecutor.Query <Driver>(Arg.Any <string>()).Returns(new List <Driver>()); // 2 способ: // var getDriverSql = $@" //select * //from Drivers //where Id = {driverId}; //"; // dbExecutor.Query<Driver>(getDriverSql).Returns(new List<Driver>()); #endregion #region IDbExecutorFactory var dbExecutorFactory = Substitute.For <IDbExecutorFactory>(); dbExecutorFactory.Create(appSettings.ConnectionStrings.OrdersDb).Returns(dbExecutor); #endregion var handler = CreateTestedComponent(appSettings, dbExecutorFactory); var request = new SetDriverForOrderCommandRequest() { OrderId = orderId, DriverId = driverId }; // Act var result = await handler.Handle(request, CancellationToken.None); // Assert Assert.True(result.Failure); Assert.Contains("Назначаемый водитель не найден", result.ToMultiLine()); }
public async Task Handle__CreateNewOrderIsFail__ReturnFailure_v1() { // Arrange var errorMessage = $"test-error: {_faker.Random.Words()}"; var notifier = Substitute.For <INotifier>(); var dbContext = Substitute.For <OrderContext>(); var appSettings = AppSettingsFake.Generate(); #region DbContext // Минусы: // 1) приходится вникать в логику сохранения нового заказа; // 2) приходится ее воспроизводить, да так, чтобы не возникло ошибок: // - если мы не зададим, DbSet<Orders> - получим NRE // - если не зададим поведение SaveChanges() - он выполнится успешно, и мы получим не тот // результат, который ожидаем var ordersDbSet = Substitute.For <DbSet <Order> >(); dbContext.Orders = ordersDbSet; dbContext.SaveChanges().Throws(new Exception(errorMessage)); #endregion #region DbContextFactory var dbContextFactory = Substitute.For <IDbContextFactory <OrderContext> >(); dbContextFactory.Create(appSettings.ConnectionStrings.OrdersDb).Returns(dbContext); #endregion var handler = CreateTestedComponent(appSettings, dbContextFactory, notifier); var commandRequest = GenerateCommandRequest(); // Act var result = await handler.Handle(commandRequest, CancellationToken.None); // Assert Assert.True(result.Failure); Assert.Contains(errorMessage, result.ToMultiLine()); }