I'm using the Moq framework for my unit tests, and I recently wrote a test for checking that a property on one of my DTOs was set within a method.
Originally, the DTO was returned by my methods....then the property set. Here's the method that I'm testing.
public void UpdatePlayerProfileStatistics(DataRow playerRecord, bool useUpdatedGamesPlayed = true)
{
DTOProfile.Player player = this._playerDataParser.ParsePlayerProfileData(playerRecord);
DTOProfile.Player playerInDatabase = this._playerManager.MatchPlayerInDatabase(player.Id);
string errorMessage = String.Empty;
if (useUpdatedGamesPlayed)
{
// do nothing. player.Games = player.Games; nothing changes
}
else
{
// we want to keep the Games played from the value of the player in the database.
player.Games = playerInDatabase.Games;
}
if (!this.repository.UpdatePlayerProfile(player, out errorMessage))
{
throw new InvalidOperationException(errorMessage);
}
}
For my test, I would mock ParsePlayerProfileData and MatchPlayerInDatabase, but to test the setting of the .Games property, I needed to add an IPlayer interface to Player. I'd then make ParsePlayerProfileData and MatchPlayerInDatabase to return the interface.
DTOProfile.IPlayer player = this._playerDataParser.ParsePlayerProfileData(playerRecord);
DTOProfile.IPlayer playerInDatabase = this._playerManager.MatchPlayerInDatabase(player.Id);
Then in my test, I have:-
var mockUpdatedPlayer = new Mock<IPlayer>();
var mockDatabasePlayer = new Mock<IPlayer>();
_playerDataParser.Setup(p => p.ParsePlayerProfileData(It.IsAny<DataRow>())).Returns(mockUpdatedPlayer.Object);
_playerManager.Setup(m => m.MatchPlayerInDatabase(It.IsAny<int>())).Returns(mockDatabasePlayer.Object);
UpdatePlayerProfileStatistics(myRow, true);
mockedPlayer.VerifySet(x => x.Games = It.IsAny<int>(), Times.Never());
This all works.
My question is, moving forward should I have interfaces for all my DTOs, and make all my methods return these interfaces (instead of the concrete type)? I figure that this will allow me perform these 'VerifySet' and 'VerifyGet's.
Or, is there a better way to test this?