c# - 起订量设置报告“表达式不是方法调用”
问题描述
我计划为我们拥有的一堆服务的代理/包装器编写一个测试库。每个代理都简单地将模型转换为 TIn,调用返回 TOut 的服务上的方法。对于每个代理,唯一的变化是底层服务与每个代理内部的样板代码不同。
class TestBase<TSvc, TProxy>
{
private Mock<TSvc> svcMock = new Mock<TSvc>();
private Mock<IMapper> mapperMock = new Mock<IMapper>();
private TProxy proxy;
protected void TestServiceCall<TIn, TOut>(Func<TSvc, Func<TIn, TOut>> svcCallFunc, TInModel model,
Func<TProxy, TInModel, TOutModel> methodToTest)
{
var input= new TIn();
var svcResult = new TOut();
var proxy = ConstructProxy(this.svcMock);
this.mapperMock.Setup(m => m.Map<TInModel, TInput>(model)).Returns(input);
this.svcMock.Setup(m => svcCallFunc(m)(input)).Returns(svcResult);
this.mapperMock.Setup(m => m.Map<TOut, TOutModel>(svcResult)).Returns(output);
var result = methodToTest(model);
... verify if the svc was called etc. ...
result.Should().BeSameAs(output);
}
}
class UserService
{
QuestionModels GetQuestionsByUsers(SearchModel searchModel)
{ .. get all questions that comply with search parameters..}
TopicModels GetTopicsForUsers(TopicSearchModel searchModel)
{ .. get all topics that comply with search parameters..}
}
class UserProxy
{
private UserService service;
private Mapper mapper;
QuestionsClass GetQuestionsByUsers(SearchClass search)
{
var searchModel = mapper.Map<SearchClass, SearchModel>(search);
var svcResult = userService.GetQuestionsByUsers(searchModel);
return mapper.Map<QuestionModels, QuestionsClass>(svcResult);
}
TopicsClass GetTopicsForUsers(TopicSearchClass search)
{
var searchModel = mapper.Map<TopicSearchClass, TopicSearchModel>(search);
var svcResult = userService.GetTopicsForUsers(searchModel);
return mapper.Map<TopicModels, TopicsClass>(svcResult);
}
}
如果您可以看到,每个方法需要执行的步骤数才能达到结果是恒定的,
- 将请求映射到中间类型
- 致电服务以获取结果
- 映射&返回结果类
我有几十个这样的类,它们的作用几乎相同。他们每个人都可以有大约 5-10 种这样的方法。
所以我想做以下事情。这样我就可以节省编写样板测试代码所花费的时间。
[TestClass]
class UserProxyTest : TestBase<UserService, UserProxy>
{
[TestMethod]
void GetQuestionsByUsersTest()
{
this.TestServiceCall<SearchModel, QuestionModels>(
svc => svc.GetQuestionsByUsers,
new SearchClass(), <-- This could be anything
pxy => pxy.GetQuestionsByUsers);
}
[TestMethod]
void GetTopicsForUsers()
{
this.TestServiceCall<TopicSearchModel, TopicModels>(
svc => svc.GetTopicsForUsers,
new TopicSearchClass(), <-- This could be anything
pxy => pxy.GetTopicsForUsers);
}
}
我遇到的问题是,设置 svcMock 的行报告了一个错误,指出表达式不是方法调用。我该如何解决这个问题?
解决方案
svcMock.Setup(m => svcCallFunc(m)(input))
是无效的。
onSetup
方法Mock<T>
接受一个Expression
用于选择T
要模拟的成员。表达式的主体必须是成员访问表达式或对成员的方法调用表达式T
。其他任意表达式无效。
例如:
public interface IService1
{
int Test { get; }
void Method1();
object Method2(object input);
}
var mock = new Mock<IService1>();
// These are valid member selectors
mock.Setup(x => x.Test);
mock.Setup(x => x.Method1());
mock.Setup(x => x.Method2(null));
// These are not
mock.Setup(x => 1);
mock.Setup(x => x.Test.GetHashCode());
mock.Setup(x => this);
要对 进行有效调用Setup
,您需要 的实例Expression<Func<TSvc, TOut>>
或 的实例Expression<Action<TSvc>>
,因此您可以将TestServiceCall
方法更改为:
protected void TestServiceCall<TIn, TOut>(
Func<TIn, Expression<Func<TSvc, TOut>>> svcCallFunc)
{
var input = new TIn();
var output = new TOut();
svcMock.Setup(svcCallFunc(input)).Returns(output);
}
并称之为:
TestServiceCall<object, object>(input => svc => svc.Method2(input));
推荐阅读
- java - Java/Spring:连接到多个 BigQuery 数据集
- php - POST请求后PHP写入文件并下载
- c++ - g++ 11.2.0 读取编译模块失败:文件数据错误
- html - 如何在一个元素和它的伪元素 "::before" 之间创建一个特定的空间?CSS
- node.js - timePlayed 上的 SONOS POST 请求返回未定义的 req.body
- php - 我如何在 php 中重复一段时间 cicle?
- excel - 没有VBA的Excel中的重复单元格颜色
- rabbitmq - RabbitMQ Java 客户端连接超时
- javascript - 项目 [0] 未显示在工具提示上
- spring-boot - Spring Session Redis Web 会话到期通知不会延迟到应用程序再次启动?