unit-testing - 从使用 func 作为参数的 moq 调用扩展方法时引发异常
问题描述
我在为调用静态函数且其参数之一是 func 的方法创建单元测试时遇到问题。即使我创建了一个包装类来调用静态函数即扩展,问题仍然存在,如本文所建议的:
正如有人建议的那样,我应该创建一个接口和一个包装类,但是当它达到最小起订量设置时,我仍然遇到异常。我的设置如下所示:
context.Setup(c => new MyExtensionWapper()
.UpdateCollection<TestObject, int>(
context.Object,
databaseCollection,
detachedCollection,
o=>o.Id.Value));
错误发生在o=>o.Id.Value
MyExtensionWapper 类是 Wrapper 函数,它使用 UpdateCollection 合约实现 IExtensions。
请注意,我的 UpdateCollection 是一个通用函数,与Entity Framework
where TEntity
is an EF entity object & 和TKey
趋向于Int
.
public class MyExtensionWapper : IExtensions
{
public virtual void UpdateCollection<TEntity, TKey>(IDbContext context,
ICollection<TEntity> databaseCollection,
ICollection<TEntity> detachedCollection,
Func<TEntity, TKey> keySelector)
where TEntity : class
where TKey : IEquatable<TKey>
{
context.UpdateCollection(databaseCollection,
detachedCollection, keySelector);
}
}
当它达到 moqcontext.Setup(...
时,我收到以下错误:
System.NotSupportedException: 'Unsupported expression: o => o.Id.Value'
你能帮我吗?
谢谢。
更新-1
这是我最初的调用,我尝试直接从模拟设置中调用静态方法(扩展):
context.Setup(c => c.UpdateCollection<TestObject, int>(
databaseCollection,
detachedCollection,
o=>o.Id.Value));
我的模拟创建如下:
context = CreateMock<IDbContext>(MockBehavior.Loose);
但是当被调用时,我收到以下错误:
System.NotSupportedException: 'Invalid setup on an extension method:....
更新 2
正如@Johnny 所建议的,我应该模拟界面,所以我尝试了以下但我得到了同样的错误:
Mock<IExtensions> dbExtension;
// Note: Results are the same whether I create the mock with a loose
// behaviour or not.
dbExtension = CreateMock<IExtensions>(MockBehavior.Loose);
dbExtension.Setup(c => new MyExtensionWapper()
.UpdateCollection<TestObject, int>(
context.Object,
databaseCollection,
detachedCollection,
o=>o.Id.Value,
另外,我没有调用包装类,而是尝试直接从模拟中调用 UpdateCollection 方法,因为它是在接口中定义的,即 c=>c.UpdateCollection(databaseCollection, ...) 但无济于事。
解决方案
我最终使用@Johnny 建议的方法让它工作,该方法是模拟接口,但我必须对我的模拟做一些细微的改变:
dbExtension.Setup(c => c.UpdateCollection<TestObject, int>(
context.Object,
databaseCollection,
detachedCollection,
It.IsAny<Func<TestObject, int>>());
而不是通过
o=>o.Id.Value
我不通过
It.IsAny<Func<TestObject, int>>()
请注意,尝试传递It.IsAny<Func<TestObject, int>>()
调用包装类的原始代码不起作用并引发以下异常:
System.InvalidOperationException: 'No coercion operator is defined
between types 'Extensions.MyExtensionWapper' and 'Moq.Mock'.'
推荐阅读
- ruby - 如何强制通过 Microsoft Graph API 发送的电子邮件使用 UTF-8 编码?
- kotlin - 从 kotlin 编译器插件更改重新编译文件的列表
- javascript - 如何使用 Node.js EventEmitter 使用相同的事件处理函数处理多个事件?
- java - 数据记录文件中的 JSON 格式
- python - 计算复矩阵的行列式以检查特征值计算
- javascript - 与属性“getOptionLabel”一起使用时,material-ui 自动完成属性“值”不可用
- visual-studio - 为什么 Visual Studio 有时会使用旧代码运行?
- python - 如何最好地一次提交多个 Django formset_factory 表单?
- rabbitmq - 使用 MassTransit/RabbitMQ 更改消息优先级
- javascript - 我在 JavaScript 中收到错误“无法读取未定义的属性 'innerHTML'”。请帮忙!我是 JS 新手。代码附在下面。谢谢