2015-12-01 5 views
1

Я пишу некоторые модульные тесты для класса, а метод, который я тестирую, принимает выражение, я пытаюсь создать и выразить и передать его методу, но я получаю следующее ошибка:Создание выражения LINQ для модульного тестирования

System.ArgumentException: Static method requires null instance, non-static method requires non-null instance. Parameter name: method

[TestClass] 
public class WhenFilterProvided : FindSubscriptionsForCurrentUserTestBase 
{ 
    bool filterFuncWasCalled; 
    private Func<UserSubscription, bool> filterFunc => (userSubscription) => 
    { 
     filterFuncWasCalled = true; 
     return userSubscription.SubscriptionId == "petrol.prcies.monthly"; 
    }; 

    protected override Expression<Func<UserSubscription, bool>> Filter => 
     Expression.Lambda<Func<UserSubscription, bool>>(Expression.Call(filterFunc.Method)); 


    [TestMethod] 
    public void CallsDetailsRepository() 
    { 
     UserDetailsRepositoryMock.Verify(x => x.FindAsync("userId", CancellationToken.None), Times.Once); 
    } 

    [TestMethod] 
    public void FilterFuncGetsCalledToFilterSubscriptions() 
    { 
     Assert.IsTrue(filterFuncWasCalled); 
    } 
} 
+0

Вместо использования Expression.Call ,, почему не просто вызвать FilterFunc() или filterFunc.Invoke()? –

+1

Я думаю, что вы забыли передать параметр (userSubscription в выражении) для Expression.Call –

ответ

0

Анонимные методы реализуются иногда as instance methods. В вашем случае анонимный метод должен быть методом экземпляра, потому что вам нужно получить доступ к this, чтобы получить доступ к filterFuncWasCalled. Итак, вы пытаетесь вызвать метод экземпляра, но вы не передаете какой-либо экземпляр. Вы можете установить, что при пропускании постоянного выражения с экземпляром:

Expression.Call(Expression.Constant(filterFunc.Target), filterFunc.Method) 

Но это не будет работать, так как метод принимает параметр, и вы не пропуская никаких. Давайте используем ту же самую, которую будем использовать для выражения лямбда. Это полная Filter свойство для достижения этой цели:

Expression<Func<UserSubscription, bool>> Filter { 
    get { 
     var param = Expression.Parameter(typeof(UserSubscription)); 
     var body = Expression.Call(Expression.Constant(filterFunc.Target), filterFunc.Method, param); 
     return Expression.Lambda<Func<UserSubscription, bool>>(body, param); 
    } 
} 
Смежные вопросы