/
softailor
/
gridient
Обзор
Документация
Войти
/
softailor
/
gridient
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/Gridient.Core.Tests/Extensions/UnitOfWorkExtensionsTests.cs
220 строк
9 KB
Jenkins
Auto add
18 фев 2026, 10:19
18 фев 2026, 10:19
1e6c4f8
Код
Авторство
О чём код?
using FluentAssertions; using Gridient.Core.Extensions; using Gridient.Core.Repositories; using Microsoft.Extensions.Logging; using Moq; using Xunit; namespace Gridient.Core.Tests.Extensions { public class UnitOfWorkExtensionsTests { private readonly Mock<IUnitOfWork> _unitOfWorkMock; private readonly Mock<IUnitOfWorkTransaction> _transactionMock; private readonly Mock<ILogger> _loggerMock; public UnitOfWorkExtensionsTests() { _unitOfWorkMock = new Mock<IUnitOfWork>(); _transactionMock = new Mock<IUnitOfWorkTransaction>(); _loggerMock = new Mock<ILogger>(); _unitOfWorkMock .Setup(x => x.BeginTransactionAsync(It.IsAny<CancellationToken>())) .ReturnsAsync(_transactionMock.Object); } #region ExecuteInTransactionAsync<T> /// <summary> /// Проверяет, что ExecuteInTransactionAsync<T> успешно выполняет действие и делает commit /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithReturnValue_WhenSuccessful_ShouldCommit() { // Arrange var expectedResult = 42; // Act var result = await _unitOfWorkMock.Object.ExecuteInTransactionAsync( async transaction => await Task.FromResult(expectedResult), cancellationToken: CancellationToken.None); // Assert result.Should().Be(expectedResult); _transactionMock.Verify(x => x.CommitAsync(It.IsAny<CancellationToken>()), Times.Once); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Never); } /// <summary> /// Проверяет, что ExecuteInTransactionAsync<T> делает rollback и пробрасывает исключение при ошибке /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithReturnValue_WhenThrows_ShouldRollback() { // Arrange var exception = new InvalidOperationException("Test error"); // Act Func<Task> act = () => _unitOfWorkMock.Object.ExecuteInTransactionAsync<int>( async transaction => throw exception, cancellationToken: CancellationToken.None); // Assert await act.Should().ThrowAsync<InvalidOperationException>() .WithMessage("Test error"); _transactionMock.Verify(x => x.CommitAsync(It.IsAny<CancellationToken>()), Times.Never); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Once); } /// <summary> /// Проверяет, что ExecuteInTransactionAsync<T> логирует ошибку при наличии логгера /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithReturnValue_WhenThrows_ShouldLogError() { // Arrange var exception = new InvalidOperationException("Test error"); // Act Func<Task> act = () => _unitOfWorkMock.Object.ExecuteInTransactionAsync<int>( async transaction => throw exception, _loggerMock.Object, CancellationToken.None); // Assert await act.Should().ThrowAsync<InvalidOperationException>(); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Once); // Проверяем, что логгер был вызван (через VerifyLogError сложно, но поведение подтверждается через rollback) } /// <summary> /// Проверяет, что ExecuteInTransactionAsync<T> не логирует ошибку при отсутствии логгера /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithReturnValue_WhenThrowsWithoutLogger_ShouldNotLog() { // Arrange var exception = new InvalidOperationException("Test error"); // Act Func<Task> act = () => _unitOfWorkMock.Object.ExecuteInTransactionAsync<int>( async transaction => throw exception, logger: null, CancellationToken.None); // Assert await act.Should().ThrowAsync<InvalidOperationException>(); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Once); } #endregion #region ExecuteInTransactionAsync (void) /// <summary> /// Проверяет, что ExecuteInTransactionAsync успешно выполняет действие и делает commit /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithoutReturnValue_WhenSuccessful_ShouldCommit() { // Arrange var actionExecuted = false; // Act await _unitOfWorkMock.Object.ExecuteInTransactionAsync( async transaction => { actionExecuted = true; await Task.CompletedTask; }, cancellationToken: CancellationToken.None); // Assert actionExecuted.Should().BeTrue(); _transactionMock.Verify(x => x.CommitAsync(It.IsAny<CancellationToken>()), Times.Once); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Never); } /// <summary> /// Проверяет, что ExecuteInTransactionAsync делает rollback и пробрасывает исключение при ошибке /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithoutReturnValue_WhenThrows_ShouldRollback() { // Arrange var exception = new InvalidOperationException("Test error"); // Act Func<Task> act = () => _unitOfWorkMock.Object.ExecuteInTransactionAsync( async transaction => throw exception, cancellationToken: CancellationToken.None); // Assert await act.Should().ThrowAsync<InvalidOperationException>() .WithMessage("Test error"); _transactionMock.Verify(x => x.CommitAsync(It.IsAny<CancellationToken>()), Times.Never); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Once); } /// <summary> /// Проверяет, что ExecuteInTransactionAsync логирует ошибку при наличии логгера /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithoutReturnValue_WhenThrows_ShouldLogError() { // Arrange var exception = new InvalidOperationException("Test error"); // Act Func<Task> act = () => _unitOfWorkMock.Object.ExecuteInTransactionAsync( async transaction => throw exception, _loggerMock.Object, CancellationToken.None); // Assert await act.Should().ThrowAsync<InvalidOperationException>(); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Once); } /// <summary> /// Проверяет, что ExecuteInTransactionAsync не логирует ошибку при отсутствии логгера /// </summary> [Fact] public async Task ExecuteInTransactionAsync_WithoutReturnValue_WhenThrowsWithoutLogger_ShouldNotLog() { // Arrange var exception = new InvalidOperationException("Test error"); // Act Func<Task> act = () => _unitOfWorkMock.Object.ExecuteInTransactionAsync( async transaction => throw exception, logger: null, CancellationToken.None); // Assert await act.Should().ThrowAsync<InvalidOperationException>(); _transactionMock.Verify(x => x.RollbackAsync(It.IsAny<CancellationToken>()), Times.Once); } /// <summary> /// Проверяет, что ExecuteInTransactionAsync передает транзакцию в действие /// </summary> [Fact] public async Task ExecuteInTransactionAsync_ShouldPassTransactionToAction() { // Arrange IUnitOfWorkTransaction? receivedTransaction = null; // Act await _unitOfWorkMock.Object.ExecuteInTransactionAsync( async transaction => { receivedTransaction = transaction; await Task.CompletedTask; }, cancellationToken: CancellationToken.None); // Assert receivedTransaction.Should().BeSameAs(_transactionMock.Object); } #endregion } }