2016-11-23 15 views
4

У меня есть провал теста, который зависит от внешнего модуля. Я хочу использовать Rhino Mock для создания отчета о вызываемых функциях.Используйте Rhino Mock, чтобы сообщить о функции, которая была вызвана

Я создал минимальный пример, который иллюстрирует мою проблему:

using NUnit.Framework; 
using Rhino.Mocks; 
using System; 

namespace StackOverflow_namespace 
{ 
    public interface IUsefulService 
    { 
     object HiddenAmongManyCalls(); 
    } 

    public class ThirdPartyBase 
    { 
     private int a = 42; 

     public ThirdPartyBase(IUsefulService service) 
     { 
      object liveFastDieYoung = service.HiddenAmongManyCalls(); 
      liveFastDieYoung.Equals(a); 
     } 
    } 

    public class MyParty : ThirdPartyBase 
    { 
     public MyParty(IUsefulService service) : base(service) 
     { 

     } 
    } 


    [TestFixture] 
    class StackOverflow 
    { 
     [Test] 
     public void Hypothetical() 
     { 
      IUsefulService service = MockRepository.GenerateMock<IUsefulService>(); 

      try 
      { 
       var party = new MyParty(service); 
      } 
      catch(Exception e) 
      { 
       string[] calls = MagicallyGetTheCallsThatWereMadeToTheMock(); 
       foreach(var call in calls) 
       { 
        //with my visual studio testrunner for nunit 3 I can investigate stored console output 
        Console.WriteLine(call); 
       } 
       Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message); 
      } 
     } 

     private string[] MagicallyGetTheCallsThatWereMadeToTheMock() 
     { 
      return new[] 
      { 
       "This is where I am lost, I do not know how to get the calls from the repository." 
      }; 
     } 
    } 
} 

Я пытался найти что-то онлайн без успеха.

Do Rhino Mocks записывает все вызовы и могу ли я получить доступ к этому списку?

Edit:

Попытка проверить ожидания не работает, так как я ищу для звонков я не ожидал.

Я мог бы составить список вызовов, используя GetArgumentsForCallsMadeOn. Я могу задуматься о интерфейсе. Я начал с этого метода, но в настоящее время я не вижу, как я могу преобразовать MethodInfo в Action<T>.

private IEnumerable<string> GetCallsList<Interface>(Interface rhinomock) 
{ 
    Type interfaceType = typeof(Interface); 
    List<MethodInfo> interfaceMethodInfos = new List<MethodInfo>(); 
    List<string> returnInfos = new List<string>(); 
    StringBuilder callbuilder = new StringBuilder(); 

    foreach (var property in interfaceType.GetProperties()) 
    { 
     interfaceMethodInfos.Add(property.GetGetMethod()); 
     interfaceMethodInfos.Add(property.GetSetMethod()); 
    } 
    foreach (var method in interfaceType.GetMethods()) 
    { 
     interfaceMethodInfos.Add(method); 
    } 

    foreach (var methodinfo in interfaceMethodInfos) 
    { 
     Action<Interface> magic = null; //convert methodinfo into action - still missing 
     var calls = rhinomock.GetArgumentsForCallsMadeOn(magic); //magic is currently null, here be crash 
     foreach (var call in calls) 
     { 
      bool more = false; 
      callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('('); 
      foreach (var parameter in call) 
      { 
       if (more){ callbuilder.Append(", "); } 
       if (null == parameter) { callbuilder.Append("<null>"); } 
       else { callbuilder.Append(parameter.ToString()); } 
       more = true; 
      } 
      callbuilder.Append(')'); 
      string callInfo = callbuilder.ToString(); 
      returnInfos.Add(callInfo); 
     } 
    } 
    return returnInfos; 
} 
+0

Да, риномы записывают все вызовы методов. Вы можете проверить их выполнение с помощью AssertWasCalled. –

+0

@OldFox Я могу проверить все, что я ожидаю, но с вызовом, как выше, где что-то сделано, что я не ожидаю, что хочу создать отчет, который показывает мне, что произошло. Я не думаю, что VerifyAllExpectations сделают это для меня. – Johannes

+2

В UT вы должны проверить ожидаемое поведение. Плохая практика следить за всеми вызовами. 'VerifyAllExpectations' не решит вашу проблему. Если вы не хотите разрешать неожиданные звонки, вы должны использовать Strict mock (сегодня использование такого макета считается неудачной практикой ...). Если вы все еще хотите иметь доступ к записям: используйте reflaction или загрузите исходный код rhinomocks и внесите некоторые изменения .... –

ответ

2

Я смог использовать отражение, чтобы получить требуемый результат. Вот минимальный пример, когда тест терпит неудачу, и вывод содержит все вызовы методов.

using NUnit.Framework; 
using Rhino.Mocks; 
using System; 
using System.Collections.Generic; 
using System.Reflection; 
using System.Text; 

namespace StackOverflow_namespace 
{ 
    public interface IUsefulService 
    { 
     object HiddenAmongManyCalls(); 
     string TestCall2(string arg1, int arg2); 
     string FULLACCESS { get; set; } 
     string READONLY { get; } 
    } 

    public class ThirdPartyBase 
    { 
     private int a = 42; 

     public ThirdPartyBase(IUsefulService service) 
     { 
      service.TestCall2("callA", 1); 
      service.TestCall2("callB", 1); 
      object liveFastDieYoung = service.HiddenAmongManyCalls(); 
      service.TestCall2("callA", 2); 
      service.TestCall2("callB", 2); 
      var a = service.FULLACCESS; 
      var b = service.READONLY; 
      service.FULLACCESS = "some"; 
      liveFastDieYoung.Equals(a); 
     } 
    } 

    public class MyParty : ThirdPartyBase 
    { 
     public MyParty(IUsefulService service) : base(service) 
     { 

     } 
    } 


    [TestFixture] 
    class StackOverflow 
    { 
     [Test] 
     public void Hypothetical() 
     { 
      IUsefulService service = MockRepository.GenerateMock<IUsefulService>(); 

      try 
      { 
       var party = new MyParty(service); 
      } 
      catch (Exception e) 
      { 
       var calls = GetCallsList(service); 
       foreach (var call in calls) 
       { 
        //with my visual studio testrunner for nunit 3 I can investigate stored console output 
        Console.WriteLine(call); 
       } 
       Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message); 
      } 
     } 

     private IEnumerable<string> GetCallsList<Interface>(Interface rhinomock) 
     { 
      Type interfaceType = typeof(Interface); 
      List<MethodInfo> interfaceMethodInfos = new List<MethodInfo>(); 
      List<string> returnInfos = new List<string>(); 
      StringBuilder callbuilder = new StringBuilder(); 

      foreach (var property in interfaceType.GetProperties()) 
      { 
       AddMethodInfoIfValid(interfaceMethodInfos, property.GetGetMethod()); 
       AddMethodInfoIfValid(interfaceMethodInfos, property.GetSetMethod()); 
      } 
      foreach (var method in interfaceType.GetMethods()) 
      { 
       AddMethodInfoIfValid(interfaceMethodInfos, method); 
      } 

      foreach (var methodinfo in interfaceMethodInfos) 
      { 
       int paramcount = methodinfo.GetParameters().Length; 
       object[] args = new object[paramcount]; 
       Action<Interface> lambdacall = (i) => methodinfo.Invoke(i, args); 
       var calls = rhinomock.GetArgumentsForCallsMadeOn(lambdacall); 
       foreach (var call in calls) 
       { 
        bool more = false; 
        callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('('); 
        foreach (var parameter in call) 
        { 
         if (more) { callbuilder.Append(", "); } 
         if (null == parameter) { callbuilder.Append("<null>"); } 
         else { 
          callbuilder 
           .Append('(').Append(parameter.GetType().Name).Append(")'") 
           .Append(parameter.ToString()).Append("'"); 
         } 
         more = true; 
        } 
        callbuilder.Append(')'); 
        string callInfo = callbuilder.ToString(); 
        returnInfos.Add(callInfo); 
       } 
      } 
      return returnInfos; 
     } 

     private static void AddMethodInfoIfValid(List<MethodInfo> interfaceMethodInfos, MethodInfo methodinfo) 
     { 
      if (null != methodinfo) 
      { 
       interfaceMethodInfos.Add(methodinfo); 
      } 
     } 
    } 
} 

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

  • Нет связанных вопросов^_^