【发布时间】:2014-02-19 05:17:08
【问题描述】:
我正在尝试模拟一个返回 IEnumerable 数据集的方法,例如所有代码的列表。
有一个接口 ISystemService.cs 包含此方法,一个名为 SystemService.cs 的服务类具有方法定义。
被测系统是:
public static class CacheKeys
{
public const string ALLCURRENCYCODES = "CurrencyCodes";
}
public interface ICacheManager
{
T Get<T>(string key);
void Set(string key, object data, int cacheTime);
void Clear();
}
public interface ISessionManager
{
}
public interface IApplicationSettings
{
string LoggerName { get; }
int CacheTimeout { get; }
}
public class EFDbContext : DbContext
{
public DbSet<CurrencyCode> CurrencyCodes { get; set; }
}
public class CurrencyCode
{
public string Code { get; set; }
public string Description { get; set; }
public decimal CurrencyUnit { get; set; }
public int? DecimalPlace { get; set; }
public string BaseCurrencyCode { get; set; }
}
public interface ISystemService
{
IEnumerable<CurrencyCode> GetAllCurrencyCodes();
}
//SystemService.cs
public class SystemService : ISystemService
{
private readonly EFDbContext db;
private readonly ICacheManager cacheManager;
private readonly ISessionManager sessionManager;
private readonly IApplicationSettings appSettings;
public SystemService(EFDbContext dbContext, ICacheManager cacheManager, ISessionManager sessionManager, IApplicationSettings appSettings)
{
db = dbContext;
this.cacheManager = cacheManager;
this.sessionManager = sessionManager;
this.appSettings = appSettings;
}
public IEnumerable<CurrencyCode> GetAllCurrencyCodes()
{
var allCurrencyCodes = cacheManager.Get<IEnumerable<CurrencyCode>>(CacheKeys.ALLCURRENCYCODES);
if (allCurrencyCodes == null)
{
allCurrencyCodes = db.CurrencyCodes.ToList();
cacheManager.Set(CacheKeys.ALLCURRENCYCODES, allCurrencyCodes, appSettings.CacheTimeout);
}
return allCurrencyCodes;
}
测试方法
[TestMethod]
public void testCacheMiss()
{
List<CurrencyCode> currencycodes = new List<CurrencyCode>()
{
new CurrencyCode(){Id = 1, Code = "IND", Description = "India"},
new CurrencyCode(){Id = 2, Code = "USA", Description = "UnitedStates"},
new CurrencyCodes(){Id = 3, Code = "UAE", Description = "ArabEmirates"}
};
var mockEfContext = new Mock<EFDbContext>();
var mockCacheManager = new Mock<ICacheManager>();
var mockSessionManager = new Mock<ISessionManager>();
var mockAppSettings = new Mock<IApplicationSettings>();
// Setups for relevant methods of the above here, e.g. to test a cache miss
mockEfContext.SetupGet(x => x.CurrencyCodes)
.Returns(currencycodes); // Canned currencies
mockCacheManager.Setup(x => x.Get<IEnumerable<CurrencyCode>>(It.IsAny<string>()))
.Returns<IEnumerable<CurrencyCodes>>(null); // Cache miss
// Act
var service = new SystemService(mockEfContext.Object, mockCacheManager.Object,
mockSessionManager.Object, mockAppSettings.Object);
var codes = service.GetAllCodes();
// Assert + Verify
mockCacheManager.Verify(x => x.Get<IEnumerable<CurrencyCodes>>(
It.IsAny<string>()), Times.Once, "Must always check cache first");
mockEfContext.VerifyGet(x => x.CurrencyCodes,
Times.Once, "Because of the simulated cache miss, must go to the Db");
Assert.AreEqual(currencycodes.Count, codes.Count(), "Must return the codes as-is");
既然定义的构造函数不接受一个参数,那么如何将对象作为参数传递呢?请指教
【问题讨论】:
标签: c# unit-testing moq