私が書いたいくつかのコードをテストしようとしていますが、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 によって作成されませんでした。
パラメータ名:モック
何か案は?
編集
そこで、Moq を使用して Expression<Func<T,bool>> パラメータを使用した Mocking メソッドに従って、machine.fakes を使用せずに別のテストを作成してみました。明らかな問題であることがわかりました。実際の RoutingEngine で使用される func はモックされていません
The<IMessageRouters>()
.WhenToldTo(x => x.Where(router => router.CanRoute(Param.IsAny<ProcessSkuCostUpdated>())))
.Return(new List<IMessageRouter> {Router});
上記は、実行時に実行される Where には関係がなく、コンパイル時に func がプライベート メソッドにコンパイルされるため、実行できません。関数をモックするように思えます。インターフェイスにプッシュする必要があります。ただし、純粋にテストのために内部動作を押し上げているため、においがします。