The preamble: I have designed a strongly interfaced and fully mockable data layer class that expects the business layer to create a TransactionScope when multip
I found a great way to test this using Moq and FluentAssertions. Suppose your unit under test looks like this:
public class Foo
{
private readonly IDataLayer dataLayer;
public Foo(IDataLayer dataLayer)
{
this.dataLayer = dataLayer;
}
public void MethodToTest()
{
using (var transaction = new TransactionScope())
{
this.dataLayer.Foo();
this.dataLayer.Bar();
transaction.Complete();
}
}
}
Your test would look like this (assuming MS Test):
[TestClass]
public class WhenMethodToTestIsCalled()
{
[TestMethod]
public void ThenEverythingIsExecutedInATransaction()
{
var transactionCommitted = false;
var fooTransaction = (Transaction)null;
var barTransaction = (Transaction)null;
var dataLayerMock = new Mock();
dataLayerMock.Setup(dataLayer => dataLayer.Foo())
.Callback(() =>
{
fooTransaction = Transaction.Current;
fooTransaction.TransactionCompleted +=
(sender, args) =>
transactionCommitted = args.Transaction.TransactionInformation.Status == TransactionStatus.Committed;
});
dataLayerMock.Setup(dataLayer => dataLayer.Bar())
.Callback(() => barTransaction = Transaction.Current);
var unitUnderTest = new Foo(dataLayerMock.Object);
unitUnderTest.MethodToTest();
// A transaction was used for Foo()
fooTransaction.Should().NotBeNull();
// The same transaction was used for Bar()
barTransaction.Should().BeSameAs(fooTransaction);
// The transaction was committed
transactionCommitted.Should().BeTrue();
}
}
This works great for my purposes.