Created
February 20, 2014 08:32
-
-
Save nonnb/9109213 to your computer and use it in GitHub Desktop.
Moq code for this SO question : http://stackoverflow.com/questions/21871678/mocking-with-moq-trying-to-pass-an-object-to-constructor-having-multiple-parame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Moq; | |
using NUnit.Framework; | |
namespace WindowsFormsApplication3 | |
{ | |
public class CacheKeys | |
{ | |
public const string ALLCODES = "ALL"; | |
} | |
public interface ICacheManager | |
{ | |
T Get<T>(string s); | |
void Set(string s, object o, int timeOut); | |
} | |
public interface ISessionManager | |
{ | |
} | |
public interface IApplicationSettings | |
{ | |
int CacheTimeout { get; set; } | |
} | |
public class EFDbContext | |
{ | |
public virtual IEnumerable<SomeCodes> SomeCodes | |
{ | |
get | |
{ | |
throw new NotImplementedException(); // We're going to mock this anyway | |
} | |
} | |
} | |
public class SomeCodes | |
{ | |
public int Id; | |
public string Code; | |
public string Description; | |
} | |
public class CurrencyCodes : SomeCodes | |
{ | |
} | |
public interface ICodeService | |
{ | |
} | |
//CodeService.cs | |
public class CodeService : ICodeService | |
{ | |
private EFDbContext db; | |
private ICacheManager cacheManager; | |
private ISessionManager sessionManager; | |
private IApplicationSettings appSettings; | |
public CodeService(EFDbContext dbContext, ICacheManager cacheManager, ISessionManager sessionManager, IApplicationSettings appSettings) | |
{ | |
db = dbContext; | |
this.cacheManager = cacheManager; | |
this.sessionManager = sessionManager; | |
this.appSettings = appSettings; | |
} | |
public IEnumerable<SomeCodes> GetAllCodes() | |
{ | |
var allCodes = cacheManager.Get<IEnumerable<SomeCodes>>(CacheKeys.ALLCODES); | |
if (allCodes == null) | |
{ | |
allCodes = db.SomeCodes.ToList(); | |
cacheManager.Set(CacheKeys.ALLCODES, allCodes, appSettings.CacheTimeout); | |
} | |
return allCodes; | |
} | |
} | |
[TestFixture] | |
public class MyTestClass | |
{ | |
[Test] | |
public void testCacheMiss() | |
{ | |
var currencycodes = new List<SomeCodes> | |
{ | |
new CurrencyCodes{Id = 1, Code = "IND", Description = "India"}, | |
new CurrencyCodes{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.SomeCodes) | |
.Returns(currencycodes); // Canned currencies | |
mockCacheManager.Setup(x => x.Get<IEnumerable<SomeCodes>>(It.IsAny<string>())) | |
.Returns<IEnumerable<SomeCodes>>(null); // Cache miss | |
// Act | |
var service = new CodeService(mockEfContext.Object, mockCacheManager.Object, | |
mockSessionManager.Object, mockAppSettings.Object); | |
var codes = service.GetAllCodes(); | |
// Assert + Verify | |
mockCacheManager.Verify(x => x.Get<IEnumerable<SomeCodes>>( | |
It.IsAny<string>()), Times.Once, "Must always check cache first"); | |
mockEfContext.VerifyGet(x => x.SomeCodes, | |
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"); | |
} | |
[Test] | |
public void testCacheHit() | |
{ | |
// TODO refactor this into an object mother | |
var currencycodes = new List<SomeCodes> | |
{ | |
new CurrencyCodes{Id = 1, Code = "IND", Description = "India"}, | |
new CurrencyCodes{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>(); | |
mockEfContext.SetupGet(x => x.SomeCodes) | |
.Throws(new Exception("mustnt hit the DB at all")); | |
mockCacheManager.Setup(x => x.Get<IEnumerable<SomeCodes>>(It.Is<string>(s => s == CacheKeys.ALLCODES))) | |
.Returns(currencycodes); // Cache miss | |
// Act | |
var service = new CodeService(mockEfContext.Object, mockCacheManager.Object, | |
mockSessionManager.Object, mockAppSettings.Object); | |
var codes = service.GetAllCodes(); | |
// Assert + Verify | |
mockCacheManager.Verify(x => x.Get<IEnumerable<SomeCodes>>( | |
It.Is<string>(s => s == CacheKeys.ALLCODES)), Times.Once, "Must always check cache first"); | |
mockEfContext.VerifyGet(x => x.SomeCodes, Times.Never, "Because of the simulated cache hit, must not go to the Db"); | |
Assert.AreEqual(currencycodes.Count, codes.Count(), "Must return the codes as-is"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The EFDbContext class has DbSet method
public class EFDbContext
{
public DbSet CurrencyCodes { get; set; }
}
This line:
mockEfContext.SetupGet(x => x.SomeCodes)
.Returns(currencycodes);
is throwing error.
Does the DbSet got to do anything?