2013-04-18 3 views
0

я следующий интерфейс, который используется для DI и МОК клиентов веб-сервисавызов Moq функции с выражением

public interface IWcfServiceClientProvider <TContract>: IDisposable where TContract: class 
{ 

    TResult Execute<TResult>(Expression<Func<TContract, TResult>> expression); 
    TResult Execute<TResult>(Expression<Func<TContract, TResult>> expression, bool closeConnection = true); 

    void Execute(Expression<Action<TContract>> expression); 
    void Execute(Expression<Action<TContract>> expression, bool closeConnection = true); 


} 

В моем тестовом классе у меня есть следующие:

List<BaseLookup> myList = new List<BaseLookup> { 
         new BaseLookup { Id =1, Code = "1001"}, 
         new BaseLookup { Id =2, Code = "1002"}, 
         new BaseLookup { Id =3, Code = "1003"}}; 

В моем методе испытания

Mock<IWcfServiceClientProvider<ILookupService>> lookupServiceClinetProvider = new Mock<IWcfServiceClientProvider<ILookupService>>(); 

var controller = new ElectorSearchController(lookupServiceClinetProvider.Object); 
lookupServiceClinetProvider.Setup(mock => mock.Execute(lookup => lookup.GetList(10))).Returns(myList).Verifiable(); 

    var list = controller.testMethod(); 

    lookupServiceClinetProvider.VerifyAll(); 

список будет иметь значение, если для параметра GetList установлено значение 10, то есть GetList(10) Не GetList(i) где я = 10

следующие работы

lookupServiceClinetProvider.Setup(mock => mock.Execute(It.IsAny<Expression<Func<ILookupService, List<BaseLookup>>>>(), true)).Returns((List<BaseLookup>)myList).Verifiable(); 

Но я хочу, чтобы дразнить призыв к GetList и не любой вызов Execute. Если это работает, то я могу фильтровать значения в Return методы

+0

Кто-нибудь знает, что мне не хватает? Спасибо –

+0

Я также попробовал Mocking ILookupService. Но Execute не соответствовал этому. Я попробовал решение по адресу http://stackoverflow.com/questions/16124263/moq-linq-expression-in-repository-specify-expression-in-setup, все еще не работало. –

ответ

0

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

public static bool ExpressionMatcher<TIn, TResult>(Expression<Func<TIn, TResult>> expr1, Expression<Func<TIn, TResult>> expr2) 
    { 
     if (expr1 == null || expr2 == null) 
     { 
      return false; 
     } 

     if (expr1 == expr2) 
     { 
      return true; 
     } 

     if (expr1.Type != expr2.Type) 
     { 
      return false; 
     } 

     if (expr1.Body == expr2.Body) 
     { 
      return true; 
     } 

     if (expr1.Body.NodeType != expr2.Body.NodeType) 
     { 
      return false; 
     } 

     if (expr1.Body.NodeType == ExpressionType.Call) 
     { 
      dynamic expr1Body = expr1.Body; 
      dynamic expr2Body = expr2.Body; 

      if (expr1Body.Method.Name == expr2Body.Method.Name && 
       expr1Body.Method.ReturnType == expr2Body.Method.ReturnType) 
      { 
       if (expr1Body.Arguments == null && expr2Body.Arguments == null) 
       { 
        return true; 
       } 

       if (expr1Body.Arguments.Count != expr2Body.Arguments.Count) 
       { 
        return false; 
       } 

       return true; 
      } 
     } 

     return false; 

    } 

Я использовал следующий называть

Expression<Func<ILookupService, List<BaseLookup>>> expr = lookup => lookup.GetMyList(It.IsAny<long>()); 
.Setup(mock => mock.Execute(It.Is<Expression<Func<ILookupService, List<BaseLookup>>>>(method => ExpressionMatcher(method, expr)))) 
.Returns(myList) 
.Verifiable(); 

Мне не нужно проверять тип аргументов в этой точке. Если у вас есть лучший ответ, сообщите мне, пожалуйста,

Смежные вопросы