I just keep stumbling through mocking...
The latest disaster was not grokking that I need to actually push results inside a mock object of IEnumerable...
Here's a sample (demonstration only of IEnumerable, not actually good Interaction-based testing!):
using System;
using System.Collections.Generic;
using Rhino.Mocks;
using MbUnit.Framework;
[TestFixture]
public class ZooTest{
[Test]
public void ZooCagesAnimals()
{
MockRepository mockery = new MockRepository();
IZoo zoo = new Zoo();
//this is the part that feels wrong to create
IList<IAnimal> mockResults = mockery.DynamicMock<IList<IAnimal>>();
IAnimal mockLion = mockery.DynamicMock<IAnimal>();
IAnimal mockRhino = mockery.DynamicMock<IAnimal>();
using (mockery.Record())
{
Expect.Call(zoo.Animals)
.Return(mockResults)
.Repeat.Once();
}
using (mockery.Playback())
{
zoo.CageThe(mockLion);
zoo.CageThe(mockRhino);
Assert.AreEqual(mockResults, new List<IAnimal>(zoo.Animals));
}
}
}
public class Zoo : IZoo
{
private IList<IAnimal> animals = new List<IAnimal>();
public void CageThe(IAnimal animal)
{
animals.Add(animal);
}
public IEnumerable<IAnimal> Animals
{
get
{
foreach(IAnimal animal in animals)
{
yield return animal;
}
}
}
}
public interface IAnimal
{
}
public interface IZoo
{
IEnumerable<IAnimal> Animals { get;}
void CageThe(IAnimal animal);
}
I don't like how I got it to work for the following reasons:
- Had to consume the IEnumerable results into IList, I understand this puts the results for checking onto the heap
- Had to setup the contents of the results ... I understand this as well, but my main point is to test that Zoo.Animals is returning IEnumerable, and even better, that we're using "yield return" inside
Any suggestions on doing this better, or simpler?
Edit: I'm trying to determine the optimal way to test the interaction between IEnumerable and whatever I'm using. I'm not trying to test that Zoo can hold animals, rather that Zoo exposese as IEnumerable, and that yield return
is getting used as well.