195 lines
5.8 KiB
C#
195 lines
5.8 KiB
C#
using e_suite.Database.Core.UnitTests.Helpers;
|
|
using e_suite.Database.Core.UnitTests.Helpers.Tables;
|
|
using eSuite.Core.Clock;
|
|
using Moq;
|
|
using NUnit.Framework;
|
|
|
|
namespace e_suite.Database.Core.UnitTests;
|
|
|
|
[TestFixture]
|
|
public class SunDatabaseEntityContextUnitTests
|
|
{
|
|
protected TestDbContextFactory testDbContextFactory = null!;
|
|
protected Mock<IClock> _clockMock = null!;
|
|
public DateTimeOffset TestNow = DateTimeOffset.Now;
|
|
|
|
protected TestDbContext TestDbContext = null!;
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
testDbContextFactory = new TestDbContextFactory();
|
|
|
|
_clockMock = new Mock<IClock>();
|
|
_clockMock.Setup(x => x.GetNow).Returns(() => TestNow);
|
|
|
|
TestDbContext = testDbContextFactory.CreateContext(_clockMock.Object);
|
|
}
|
|
|
|
[Test]
|
|
public void OnModelCreating_Executes_WithoutExceptions()
|
|
{
|
|
//Arrange
|
|
//Act
|
|
// dealt with by the Setup method, as this ensures the database is created.
|
|
|
|
//Assert
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public async Task TransActionAsyncAction_Executing_CodeRunsInATransaction()
|
|
{
|
|
//Arrange
|
|
Guid? transactionId = null;
|
|
|
|
|
|
//Act
|
|
await TestDbContext.TransactionAsync(async () =>
|
|
{
|
|
transactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
|
|
await TestDbContext.SaveChangesAsync();
|
|
});
|
|
|
|
//Assert
|
|
Assert.That(transactionId, Is.Not.Null); //Was in a transaction when the code was executed
|
|
Assert.That(TestDbContext.Database.CurrentTransaction?.TransactionId, Is.Null); //No longer in a transaction
|
|
}
|
|
|
|
[Test]
|
|
public async Task TransActionAsyncAction_AlreadyInTransaction_DoesNotStartAnotherTransaction()
|
|
{
|
|
//Arrange
|
|
Guid? transactionId = null;
|
|
Guid? innerTransactionId = null;
|
|
|
|
await TestDbContext.TransactionAsync(async () =>
|
|
{
|
|
transactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
|
|
|
|
//Act
|
|
await TestDbContext.TransactionAsync( async () =>
|
|
{
|
|
innerTransactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
|
|
await TestDbContext.SaveChangesAsync();
|
|
});
|
|
});
|
|
|
|
//Assert
|
|
Assert.That(transactionId, Is.Not.Null); //Was in a transaction when the code was executed
|
|
Assert.That(innerTransactionId, Is.EqualTo(transactionId)); //The inner transaction is the same as the outer transaction. Transaction inception is not allowed.
|
|
}
|
|
|
|
[Test]
|
|
public async Task TransActionAsyncAction_InsertedRecordWithNoException_TransactionCompletes()
|
|
{
|
|
//Arrange
|
|
var newItem = new TableWithKey()
|
|
{
|
|
Id = 2,
|
|
TotalTimeMS = 5000
|
|
};
|
|
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
|
|
|
|
//Act
|
|
await TestDbContext.TransactionAsync(async () =>
|
|
{
|
|
TestDbContext.TableWithKey.Add(newItem);
|
|
await TestDbContext.SaveChangesAsync();
|
|
});
|
|
|
|
//Assert
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(2));
|
|
}
|
|
|
|
[Test]
|
|
public async Task TransActionAsyncAction_InsertedRecordThenException_TransactionIsRolledback()
|
|
{
|
|
//Arrange
|
|
var newItem = new TableWithKey()
|
|
{
|
|
Id = 2,
|
|
TotalTimeMS = 5000
|
|
};
|
|
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
|
|
|
|
//Act
|
|
try
|
|
{
|
|
await TestDbContext.TransactionAsync(async () =>
|
|
{
|
|
TestDbContext.TableWithKey.Add(newItem);
|
|
await TestDbContext.SaveChangesAsync();
|
|
|
|
throw new Exception("Testing rollback");
|
|
});
|
|
}
|
|
catch
|
|
{
|
|
//This was supposed to happen
|
|
}
|
|
|
|
//Assert
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public async Task TransActionAsyncFunc_Executing_CodeRunsInATransaction()
|
|
{
|
|
//Arrange
|
|
Guid? transactionId = null;
|
|
|
|
//Act
|
|
var result = await TestDbContext.TransactionAsync(async () =>
|
|
{
|
|
transactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
|
|
|
|
await TestDbContext.SaveChangesAsync();
|
|
return true;
|
|
});
|
|
|
|
//Assert
|
|
Assert.That(result, Is.True);
|
|
Assert.That(transactionId, Is.Not.Null); //Was in a transaction when the code was executed
|
|
Assert.That(TestDbContext.Database.CurrentTransaction?.TransactionId, Is.Null); //No longer in a transaction
|
|
}
|
|
|
|
[Test]
|
|
public async Task TransActionAsyncFunc_InsertedRecordThenException_TransactionIsRolledback()
|
|
{
|
|
//Arrange
|
|
var newItem = new TableWithKey()
|
|
{
|
|
Id = 2,
|
|
TotalTimeMS = 5000
|
|
};
|
|
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
|
|
|
|
//Act
|
|
try
|
|
{
|
|
var result = await TestDbContext.TransactionAsync(async () =>
|
|
{
|
|
TestDbContext.TableWithKey.Add(newItem);
|
|
await TestDbContext.SaveChangesAsync();
|
|
|
|
throw new Exception("Testing rollback");
|
|
|
|
#pragma warning disable CS0162
|
|
//This code will never be hit because this is a test, but it's needed so that the code will compile.
|
|
return 1;
|
|
#pragma warning restore CS0162
|
|
});
|
|
}
|
|
catch
|
|
{
|
|
//This was supposed to happen
|
|
}
|
|
|
|
//Assert
|
|
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
|
|
}
|
|
} |