Reinstated a Repository - Moq cannot mock EF IDbSet so I decided that bringing the repository back would be a good idea. Example unit test below:
[TestMethod]public void ListInventoryTest(){Mock<IDbContext> context = new Mock<IDbContext>();Mock<AssetRepository> assetRepository = new Mock<AssetRepository>(context.Object);Mock<StockpileRepository> stockpileRepository = new Mock<StockpileRepository>(context.Object);List<Asset> assets = new List<Asset>();assets.Add(new Asset() { AssetId = 1 });assets.Add(new Asset() { AssetId = 2 });Stockpile stockpile = new Stockpile() { StockPileId = 1, Assets = assets };//assetRepository.Setup(x=>x.GetSingle(It.IsAny<expression<func<asset, bool="">>>())).Returns(asset);<expression<func<asset,>stockpileRepository.Setup(x => x.GetSingle(It.IsAny<Expression<Func<Stockpile, bool>>>(), It.IsAny<IEnumerable<string>>(), It.IsAny<bool>())).Returns(stockpile);var inventoryService = new InventoryService( stockpileRepository.Object, assetRepository.Object );List<Asset> rv = inventoryService.ListInventory("Hailes", "Jita01");Assert.IsNotNull(rv);Assert.IsTrue(rv.Count == 2);}
Then, now that I had a repository I could add a Null Object pattern solution to my repository, which was a bit tricker than I expected. In order to create a new T in the generic method, I needed to include a generic constraint to ensure T had a blank constructor.
public virtual T GetSingle<T>(Expression<Func<T, bool>><func whereClause, IEnumerable<string> customIncludes = null, bool overrideDefaultIncludes = false) where T : new()<string><func {IQueryablequery = (IQueryable )this.ApplyIncludesToSet(customIncludes, overrideDefaultIncludes); T val = query.SingleOrDefault(whereClause);if (val == null){val = new T();}return val;}
The final issue I resolved was picking an appropriate lifetime manager for the EF DbContext when running in an 'application' context. Using the PerResolveLifetimeManager ensures that when resolving a class, any common Dependency in the entire resolve pat are shared - this means that a service with two repository dependencies, which both depend on a dbContext, will both use the same dbContext when the service is resolved - yay. This does exactly what I want it to, each operation should use a new service instance, which will use a single dbContext across all repository actions within that method.
So yeah, productive (and thanks to @wolfbyte for the generic constraint tip).
Next job to flesh out my unit tests, and continue on the functionality, as this covered the majority of my architecture issues.
No comments:
Post a Comment