Rhino Mock to perform return returns

I am trying to write unit test to check for parsing errors. I transfer the data from the file, parse it and return the result of the analysis with the return of profitability, and then transfer it to the data layer in the volume insert.

I'm having trouble mocking a call to the data layer. Since he mocked him, he never lists the values ​​from the yield yield, and so my parsing method is never executed.

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; } } } 

I tried something like this that clearly does not work.

 [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); } } 
+4
source share
1 answer

One of the best solutions would be to put the material that happens in "// do magic" in a separate method so that it can be a unit test in isolation - without having to call the while loop from the inside, which StreamReader processes.

The problem you see is related to lazy enumeration evaluation. Since none of your test codes actually lists “things,” the state machine that is created “behind the scenes” to process the iterator block is never processed.

You will need to list the elements for the actual execution of the logic in the Parse method. You can do this with the Rhino.Mocks "WhenCalled" method (I show the AAA syntax since I don’t remember how to use the record / play semantics):

NOTE. This is unverified code.

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

What happens when the Save method is called on your stub, "WhenCalled" passes the parameter (m), which contains information about the called method. Take the first argument (things), drop it until IEnumerable<string> and get its score. This will result in an evaluation of the enumerable.

+3
source

Source: https://habr.com/ru/post/1395451/


All Articles