2012-02-08 5 views
4

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

У меня возникли проблемы, издеваясь над вызовом слоя данных. Поскольку это насмехается, он никогда не перечисляет значения из доходности yield, и поэтому мой метод разбора никогда не выполняется.

public class Processor 
{ 
    public IUnityContainer Container { get; set; } 

    public void ProcessFile(Stream stream) 
    { 
     var datamanager = Container.Resolve<IDataManager>();            
     var things = Parse(stream);   
     datamanager.Save(things);         
    } 

    IEnumerable<string> Parse(Stream stream) 
    { 
     var sr = new StreamReader(stream); 
     while (!sr.EndOfStream) 
     { 
      string line = sr.ReadLine(); 
      // do magic 
      yield return line; 
     } 
    } 
} 

Я пробовал что-то вроде этого, которое явно не работает.

[TestMethod]   
[ExpectedException(typeof(ApplicationException))] 
public void ProcessFile_InvalidInput_ThrowsException() 
{ 
    var mock = new MockRepository(); 

    var stream = new MemoryStream(); 
    var streamWriter = new StreamWriter(stream);     
    streamWriter.WriteLine("\\:fail"); 
    streamWriter.Flush(); 
    stream.Position = 0; 

    var datamanager = mock.Stub<IDataManager>();       
    TestContainer.RegisterInstance(datamanager); 

    var repos = new ProcessingRepository(); 
    TestContainer.BuildUp(repos); 

    using (mock.Record()) 
    {       
     Expect.Call(file.InputStream).Return(stream);        
     Expect.Call(delegate() { repos.Save(new List<string>()) }).IgnoreArguments(); 
    } 
    using (mock.Playback()) 
    { 
     repos.ProcessFile(stream); 
    } 
} 

ответ

3

Одним оптимальным решением было бы поместить материал, который происходит в «// колдовать» в отдельный метод, поэтому он может быть протестированы в изоляции - без необходимости вызывается внутри цикла в то время как который обрабатывает StreamReader.

Проблема, которую вы видите, объясняется ленивой оценкой перечисления. Поскольку ни один из ваших тестовых кодов фактически не перечисляет «вещи», конечный автомат, который создается «за кулисами» для обработки блока итератора, никогда не обрабатывается.

Вам нужно будет перечислить элементы для фактического выполнения логики в методе анализа. Вы можете сделать это мой с помощью метода Rhino.Mocks «WhenCalled» (я показываю синтаксис ААА, так как я не помню, как использовать запись/воспроизведение семантики):

ПРИМЕЧАНИЕ: Это непроверенный код

datamanager.Stub(d => d.Save(null)).IgnoreArguments().WhenCalled(m => int count = ((IEnumerable<string>)m.Arguments[0]).Count()); 

Что происходит, когда вызывается метод Save на вашем заглушке, «WhenCalled» передается параметр (m), который содержит информацию о вызванном методе. Возьмите первый аргумент (вещи), отбросьте его до IEnumerable<string> и получите его счет. Это приведет к оценке перечислимого.

+0

WhenCalled был именно тем, что я искал. Благодаря! – bmancini

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

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