C# Unit test Moq
▌Introduction
1. Mock instance
2. Mock.of
3. Mock.of (Setup in lambda)
▋Related articles
▌Environment
▋Visual Studio 2017 community
▋dotnet core 2.2.101
▋Moq 4.10.1
▌Implement
We
will test the GetAge(…) function of class, BirthdayRepository. It has
some dependencies inside as following,
l
IDataAccessService: responsible for fetching someone’s birthday from
database
l
ILogger:
Logger
▋Interfaces and Classes
▋BirthdayRespository.cs
public class BirthdayRepository : IBirthdayRepository
{
private IDataAccessService<Birthday> _dataAccess =null;
private ILogger _logger = null;
public BirthdayRepository(
IDataAccessService<Birthday> dataAccess,
ILogger logger
)
{
if(dataAccess!=null) this._dataAccess = dataAccess;
if(logger!=null) this._logger = logger;
}
public int GetAge(string idNumber)
{
Birthday birthday = this._dataAccess.Get(idNumber);
int age = DateTime.Now.Year - birthday.Year;
this._logger.Info($"{idNumber}'s age is {age.ToString()}");
return age;
}
public void Dispose()
{
}
}
▋IBirthdayRespository.cs
public interface IBirthdayRepository : IDisposable
{
int GetAge(string idNumber);
}
▋IDataAccessService
public interface IDataAccessService<T>
{
string ConnectionStr { get; set; }
T Get(string id);
}
▋ILogger
public interface ILogger
{
void Info(string msg);
}
▋Unit test by Mock instance
const int targetYear = 2001;
var birthday = new Birthday() {
Year = targetYear,
Month = 10,
Day = 18
};
int expected = DateTime.Now.Year - targetYear;
int actual = 0;
#region Mock instance
var mockLogger = new Mock<ILogger>();
var mockDataAccess = new Mock<IDataAccessService<Birthday>>();
mockDataAccess.SetupProperty(s => s.ConnectionStr);
mockDataAccess.Object.ConnectionStr = string.Empty;
mockDataAccess.Setup(x => x.Get(It.IsAny<string>())).Returns(birthday);
IBirthdayRepository birthdayRepository = new BirthdayRepository(mockDataAccess.Object, mockLogger.Object);
actual = birthdayRepository.GetAge("YYYYYY");
mockDataAccess.Verify(x => x.Get(It.IsAny<string>()), Times.Once);
#endregion
Assert.AreEqual(expected, actual);
▋Unit test by Mock.of
We can replace the codes in region with Mock.of
#region Mock.of
var mockLogger = Mock.Of<ILogger>();
var mockDataAccess = Mock.Of<IDataAccessService<Birthday>>();
mockDataAccess.ConnectionStr = string.Empty;
Mock.Get(mockDataAccess).Setup(x => x.Get(It.IsAny<string>())).Returns(birthday);
IBirthdayRepository birthdayRepository = new BirthdayRepository(mockDataAccess, mockLogger);
actual = birthdayRepository.GetAge("YYYYYY");
#endregion
▋Unit test by Mock.of (Setup in lambda)
Or even graceful,
#region Mock.of
(Setup in lambda)
var mockLogger = Mock.Of<ILogger>();
var mockDataAccess = Mock.Of<IDataAccessService<Birthday>>(x => x.ConnectionStr == string.Empty && x.Get(It.IsAny<string>()) == birthday);
IBirthdayRepository birthdayRepository = new BirthdayRepository(mockDataAccess, mockLogger);
actual = birthdayRepository.GetAge("YYYYYY");
#endregion
▌Reference
沒有留言:
張貼留言