Real Properties With Moq

They're real and they're spectacular!

I was recently using the C# Moq mocking library, and I needed to not only initialize a property to a value, but I needed the property to be updated by the code.

The basic setup of my interfaces was like this:

interface IAccount
{
	IList<ITransaction> Transactions { get; set; }
}

interface ITransaction
{
	DateTime Timestamp { get; set; }
}

And the ASP.NET MVC controller code under test was doing this:

IAccount account;
account.Transactions = account.Transactions.OrderBy(x => x.Timestamp).ToList();

var viewModel = new OurViewModel();
viewModel.Account = account;

My test class initialized an IAccount like this:

var transactions = new List<ITransaction>
{
	new Transaction { Timestamp = new DateTime(2019, 03, 14) },
	new Transaction { Timestamp = new DateTime(2019, 01, 01) }
}

var mockIAccount = new Mock<IAccount>();
mockIAccount.Setup(x => x.Transactions).Returns(transaction);

I wanted to verify that the controller code would sort the Transactions correctly. I could try abusing VerifySet, but that would mean I’m testing the implementation rather than the outcome (not something I wanted to do). What I really needed was Moq to allow setting and reading this property. As it turns out, Moq can do this with SetupProperty!

For Moq to make a working property, simply call SetupProperty, optionally passing a second parameter that will set the initial property value.

mockIAccount.SetupProperty(x => x.Transactions, transactions);

Now, after we call out controller code, we can access the contents of this property in our test:

OurViewModel viewModel = ourController.CallUnderTest();
Assert.AreEqual(new DateTime(2019, 01, 01), viewModel.Account.Transactions[0].Timestamp);
Assert.AreEqual(new DateTime(2019, 03, 14), viewModel.Account.Transactions[1].Timestamp);

Pretty slick if you ask me!

P.S. Yes, I realize the real issue here is our controller shouldn’t be modifying the order of the Transactions in our Account class. No one ever said real software development was perfect.

Back to Blog Posts



You may also like:

Blazor: First Look and Impressions

My impressions after a first look at Blazor and WebAssembly Read more...

Don't Copy and Paste from Stack Overflow

Why copying and pasting code from the Internet is bad for you and bad for your code base. Read more...

Bill Split and Tip Updated

A new release of an old classic Read more...