2

私が書いたいくつかのコードをテストしようとしていますが、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 がプライベート メソッドにコンパイルされるため、実行できません。関数をモックするように思えます。インターフェイスにプッシュする必要があります。ただし、純粋にテストのために内部動作を押し上げているため、においがします。

4

2 に答える 2