gpt4 book ai didi

c# - 带有 IQueryable 扩展方法的最小起订量

转载 作者:太空宇宙 更新时间:2023-11-03 15:30:11 24 4
gpt4 key购买 nike

总的来说,我是 Moq 框架和单元测试的新手,我正在尝试为下面的存储库函数创建一个单元测试。

存储库方法

public IQueryable<Campaign> AllIncluding(params Expression<Func<Campaign, object>>[] includeProperties)
{
IQueryable<Campaign> query = _context.Campaigns;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}

使用最小起订量设置进行单元测试

//Arrange
var data = new List<Models.Campaign>
{
new Models.Campaign { Id = 1, Name = "Campaign Past", StartDate = DateTime.Now.AddDays(-10), EndDate = DateTime.Now.AddDays(-5) },
new Models.Campaign { Id = 2, Name = "Campaign Active", StartDate = DateTime.Now.AddDays(-4), EndDate = DateTime.Now.AddDays(3) },
new Models.Campaign { Id = 2, Name = "Campaign Future", StartDate = DateTime.Now.AddDays(4), EndDate = DateTime.Now.AddDays(10) }
}.AsQueryable();
var _moqSet = new Mock<DbSet<Models.Campaign>>();
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.Provider).Returns(data.Provider);
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.Expression).Returns(data.Expression);
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.ElementType).Returns(data.ElementType);
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
//_moqSet.As<IQueryable<Models.Campaign>>()
// .Setup(m => m.Include(It.IsAny<Expression<Func<Models.Campaign, object>>>()))
// .Returns((Expression<Func<Models.Campaign, object>> predicate) =>
// {
// return _moqSet.Object.Include(predicate);
// });
var _moqContext = new Mock<Context.IPrizeSelectionContext>();
_moqContext.Setup(m => m.Campaigns).Returns(_moqSet.Object);
Func<IQueryable<Models.Campaign>, Expression<Func<Models.Campaign, object>>, IQueryable<Models.Campaign>> includeMethod = (query, expression) =>
{
return query.Include(expression);
};
//Act
List<Models.Campaign> allResults = null;
using (var sut = new CampaignRepository(_moqContext.Object, includeMethod))
{
allResults = sut.AllIncluding(o => o.Id, o => o.Name).OrderBy(o => o.Id).ToList();
}
//Assert
Assert.IsNotNull(allResults);
Assert.AreEqual(3, allResults.Count);
Assert.IsNull(allResults[0].StartDate);

我在 query.include(includeProperty) 之后得到一个空数据我试图模拟包含函数,但我得到一个 Expression references a method that does not belong to the mocked object: m => m.Include<Campaign,Object>(It.IsAny<Expression'1>())尝试设置 Mock DbSet 时出现异常。经过一番挖掘后,我发现 Moq 有问题或无法模拟扩展方法,请参阅 Question Mocking Extionsion Methods with Moq

按照 This Blog 中的步骤操作我尝试执行委托(delegate)模式

存储库重写

Func<IQueryable<Campaign>, Expression<Func<Campaign, object>>, IQueryable<Campaign>> _includeMethod = null;
...
public CampaignRepository(IPrizeSelectionContext context, Func<IQueryable<Campaign>, Expression<Func<Campaign, object>>, IQueryable<Campaign>> includeMethod)
: this(context)
{
_includeMethod = includeMethod;
}
...
public IQueryable<Campaign> AllIncluding(params Expression<Func<Campaign, object>>[] includeProperties)
{
IQueryable<Campaign> query = _context.Campaigns;
foreach (var includeProperty in includeProperties)
{
if (_includeMethod == null)
query = query.Include(includeProperty);
else
query = _includeMethod(query, includeProperty);
}
return query;
}

这是我的单元测试设置

Func<IQueryable<Models.Campaign>, Expression<Func<Models.Campaign, object>>, IQueryable<Models.Campaign>> includeMethod = (query, expression) =>
{
return query.Include(expression);
};

List<Models.Campaign> allResults = null;
using (var sut = new CampaignRepository(_moqContext.Object, includeMethod))
{
allResults = sut.AllIncluding(o => o.Id, o => o.Name).OrderBy(o => o.Id).ToList();
}

但是这个模式也以同样的方式结束,IQueryable<Campaign> query = _context.Campaigns;返回 Mock 类型,但我不能使用扩展方法。

任何人都可以指出正确的方向来测试我的存储库方法吗?

最佳答案

看起来您正在尝试在这里测试两件事:1.包括扩展方法2.AllIncluding方法

我建议您将 Include 方法分离到不同的静态类中,例如:

public static class CollectionExtensions {
public static Include(this IQueryable<Campaign>, Expression<Func<Campaign, object>> includeProperty) {
// put implementation here
}}

这样就可以单独测试Include方法了。 (无论如何,大部分逻辑似乎都在 include 方法中)

此外,我认为您不能在 _moqSet 设置中使用 _moqSet.Object,如下所示。这可能是导致 moq 无法解析表达式的原因。

_moqSet.As<IQueryable<Models.Campaign>>()
.Setup(m => m.Include(It.IsAny<Expression<Func<Models.Campaign, object>>>()))
.Returns((Expression<Func<Models.Campaign, object>> predicate) =>
{
return _moqSet.Object.Include(predicate);
});

关于c# - 带有 IQueryable 扩展方法的最小起订量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34034432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com