У меня есть класс CustomerService, который копирует объект клиента и выполняет хранимую процедуру для сохранения этой копии в базе данных. Мне нужно проверить этот сервис.
Служба использует TransactionScope, поскольку она находится внутри бизнес-уровня, который не должен зависеть от DbContext. Также IsolationLevel установлен на repeatableRead, потому что для создания объекта клиента он вызывает customerRepository для получения информации от исходного клиента, которая не должна изменяться в рамках этой операции.
public class CustomerService
{
public void Handle(CopyCustomer cmd)
{
using (var transaction = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
{
// Mapping newCustomer from CopyCustomer command. Includes Reading from database ...
// Use custom stored procedure !
_customerRepository.Save(newCustomer)
transaction.Complete();
}
}
}
Я также хочу проверить предыдущий метод, и мне нужно заключить вызов метода в транзакцию. Поэтому я создал еще один TransactionScope с тем же IsolationLevel, и он, кажется, работает, если только один последний вызов чтения в базу данных не ждет бесконечно.
[TestMethod]
public void CreateCustomer_Successfully()
{
// IsolationLevel.RepeatableRead has to be same as the IsolationLevel in the CustomerService.Handle method.
using (var transaction = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
{
using (var context = ContextHelper.DatabaseContext())
{
// Get number of rows in database.
customerRowsBeforeCreation = context.Customer.Count();
// Arrange: Save Original Customer into database.
customerRepository.Save(customer);
// Arrange CopyCustomer command.
var copyCustomerCommand = new CopyCustomer(){...};
// Act
customerService.Handle(copyCustomerCommand);
// Now i need to get number of customer rows in the database.
// But the last customer insert was not commited, because it is a test.
// So i probably need to call uncommited read, but anyway this row does not end,
// it is waiting infinitely.
// Get number of rows in database.
headerRowsAfterCopy = context.Header.Count();
}
// No scope.Complete => Rollback
// scope.Complete();
}
// Assert
Assert.Equals(0, exceptions.Count());
Assert.Equals(headerRowsBeforeCopy, headerRowsAfterCopy - 1);
}
Может быть, я делаю это неправильно, но как я могу решить эту проблему?