我正在尝试测试我编写的一些代码在尝试使用 Machine.Fakes (在后台使用 Moq)模拟 func 时遇到问题。有关示例,请参见下面的代码。
public class RoutingEngine : IRoutingEngine
{
private readonly IMessageRouters _messageRouters;
public RoutingEngine(IMessageRouters messageRouters)
{
_messageRouters = messageRouters;
}
public void Route<T>(T inbound)
{
var messageRouters = _messageRouters.Where(x => x.CanRoute(inbound));
foreach(var router in messageRouters)
router.Route(inbound);
}
}
public class MessageRouters : IMessageRouters
{
public IList<IMessageRouter> _routers = new List<IMessageRouter>();
public IEnumerable<IMessageRouter> Where(Func<IMessageRouter, bool> func)
{
return _routers.Where(func);
}
public void Add(IMessageRouter messageRouter)
{
_routers.Add(messageRouter);
}
}
测试就在这里
public class when_routing_a_message_with_fakes : WithSubject<RoutingEngine>
{
Establish that = () =>
{
Message = new MyMessage{ SomeValue= 1, SomeOtherValue = 11010 };
Router = The<IMessageRouter>();
Router.WhenToldTo(x => x.CanRoute(Message)).Return(true);
The<IMessageRouters>().WhenToldTo(x => x.Where(router => router.CanRoute(Message))).Return(new List<IMessageRouter> { Router });
};
Because of = () => Subject.Route(Message);
It should_do_route_the_message = () => Subject.WasToldTo(x => x.Route(Param.IsAny<MyMessage>()));
static MyMessage Message;
static IMessageRouter Router;
}
我得到了一个不受支持的上述表达式,所以我将 where 方法更改IMessageRouters
为以下内容:
public IEnumerable<IMessageRouter> Where(Expression<Func<IMessageRouter, bool>> func)
{
return _routers.Where(func.Compile());
}
现在我得到这个错误
对象实例不是由 Moq 创建的。
参数名称:模拟
有任何想法吗?
编辑
所以我尝试编写另一个没有 machine.fakes 的测试,根据Mocking 方法使用 Expression<Func<T,bool>> 参数使用 Moq。事实证明这是一个明显的问题。真实 RoutingEngine 中使用的 func 未被模拟
The<IMessageRouters>()
.WhenToldTo(x => x.Where(router => router.CanRoute(Param.IsAny<ProcessSkuCostUpdated>())))
.Return(new List<IMessageRouter> {Router});
以上与在运行时执行的 Where 无关,并且不能因为 func 在编译时被编译为私有方法。似乎要模拟函数,我需要将其推送到界面。闻起来,因为我纯粹为了测试而推动内部行为。