C# 如何模拟函数<&燃气轮机;使用机器。假货(最低起订量)?
我正在测试我编写的一些代码,这些代码遇到了使用Machine.Fakes(在引擎盖下使用Moq)模拟func的问题。有关示例,请参见下面的代码C# 如何模拟函数<&燃气轮机;使用机器。假货(最低起订量)?,c#,moq,mspec,machine.fakes,C#,Moq,Mspec,Machine.fakes,我正在测试我编写的一些代码,这些代码遇到了使用Machine.Fakes(在引擎盖下使用Moq)模拟func的问题。有关示例,请参见下面的代码 公共类路由引擎:IRoutingEngine { 专用只读IMessageRouters(消息路由器); 公共路由引擎(IMessageRouters messageRouters) { _消息路由器=消息路由器; } 公共无效路线(T入站) { var messageRouters=_messageRouters.Where(x=>x.CanRoute
公共类路由引擎:IRoutingEngine
{
专用只读IMessageRouters(消息路由器);
公共路由引擎(IMessageRouters messageRouters)
{
_消息路由器=消息路由器;
}
公共无效路线(T入站)
{
var messageRouters=_messageRouters.Where(x=>x.CanRoute(inbound));
foreach(messageRouters中的var路由器)
路由(入站);
}
}
公共类消息路由器:IMessageRouters
{
公共IList_路由器=新列表();
公共IEnumerable其中(Func Func)
{
返回_.Where(func);
}
公共无效添加(IMessageRouter消息路由器)
{
_添加(messageRouter);
}
}
测试就在这里
public类,当使用\u fakes路由\u消息时:with subject
{
确定=()=>
{
Message=newmymessage{SomeValue=1,SomeOtherValue=11010};
路由器=路由器();
Router.WhenToldTo(x=>x.CanRoute(Message)).Return(true);
().WhenToldTo(x=>x.Where(router=>router.CanRoute(Message)).Return(新列表{router});
};
因为=()=>Subject.Route(消息);
它应该路由消息=()=>Subject.WasToldTo(x=>x.route(Param.IsAny());
静态MyMessage消息;
静态IMessageRouter;
}
我得到了一个不受支持的表达式,因此我将IMessageRouters
上的where方法更改为:
public IEnumerable其中(Expression func)
{
返回_.Where(func.Compile());
}
现在我得到了这个错误
对象实例不是由Moq创建的。参数名称:mocked 有什么想法吗 编辑 所以我试着在没有机器的情况下编写另一个测试。事实证明这是一个明显的问题。真实RoutingEngine中使用的func没有被嘲笑
The()
.WhenToldTo(x=>x.Where(router=>router.CanRoute(Param.IsAny()))
.Return(新列表{Router});
以上内容与运行时执行的Where无关,并且不能在编译时将func编译为私有方法。好像是在模仿func,我需要把它推到一个接口上。闻起来就像我纯粹为了测试而提升内在行为 我找到了一种避免嘲笑
Func
的方法。我希望您对此感兴趣:)为什么不忘记广义的Where(Func)
方法,并提供具体的查询方法呢。您拥有入站邮件和路由器
及
var messageRouters=_messageRouters.For();
您现在不必模拟任何
Func
s,只需执行一个调用了assert(或以Moq中的方式)的操作即可。我发现您的测试代码存在两个问题:
IMessageRouters
上的Where()
调用的表达式过于明确。它不应该关心传递的确切函数主题
调用了Route()
。相反,您应该验证消息
是否已传递到IMessageRouter
路由器
字段,直接使用the()
[Subject(typeof(RoutingEngine))]
public class when_routing_a_message_with_fakes : WithSubject<RoutingEngine>
{
Establish that = () =>
{
Message = new MyMessage { SomeValue = 1, SomeOtherValue = 11010 };
The<IMessageRouter>().WhenToldTo(x => x.CanRoute(Message)).Return(true);
The<IMessageRouters>().WhenToldTo(x => x.Where(Param<Func<IMessageRouter, bool>>.IsAnything))
.Return(new List<IMessageRouter> { The<IMessageRouter>() });
};
Because of = () => Subject.Route(Message);
It should_route_the_message = () =>
The<IMessageRouter>().WasToldTo(x => x.Route(Message));
static MyMessage Message;
}
[主题(类型(路由引擎))]
使用伪邮件路由邮件时的公共类:with subject
{
确定=()=>
{
Message=newmymessage{SomeValue=1,SomeOtherValue=11010};
().WhenToldTo(x=>x.CanRoute(Message)).Return(true);
().WhenToldTo(x=>x.Where(Param.IsAnything))
.Return(新列表{The()});
};
因为=()=>Subject.Route(消息);
它应该路由消息=()=>
().WasToldTo(x=>x.Route(Message));
静态MyMessage消息;
}
public class RoutingEngine : IRoutingEngine
{
private readonly IMessageRouters _messageRouters;
public RoutingEngine(IMessageRouters messageRouters)
{
_messageRouters = messageRouters;
}
public void Route<T>(T inbound)
{
var messageRouters = _messageRouters.For(inbound);
foreach(var router in messageRouters)
router.Route(inbound);
}
}
public IEnumerable<IMessageRouter> For<T>() { ... }
var messageRouters = _messageRouters.For<T>();
[Subject(typeof(RoutingEngine))]
public class when_routing_a_message_with_fakes : WithSubject<RoutingEngine>
{
Establish that = () =>
{
Message = new MyMessage { SomeValue = 1, SomeOtherValue = 11010 };
The<IMessageRouter>().WhenToldTo(x => x.CanRoute(Message)).Return(true);
The<IMessageRouters>().WhenToldTo(x => x.Where(Param<Func<IMessageRouter, bool>>.IsAnything))
.Return(new List<IMessageRouter> { The<IMessageRouter>() });
};
Because of = () => Subject.Route(Message);
It should_route_the_message = () =>
The<IMessageRouter>().WasToldTo(x => x.Route(Message));
static MyMessage Message;
}