Как вы правильно издеваться в IEnumerable <T>?

голоса
6

Моя последняя катастрофа спотыкаясь насмешки не grokking , что мне нужно на самом деле толкать результаты в макете объекта IEnumerable<T>.

Вот пример (демонстрация только IEnumerable<T>, на самом деле не хорошее взаимодействие на основе тестирования!):

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

Мне не нравится, как я получил его на работу по следующим причинам:

  • Употребление IEnumerable<IAnimal>результатов в IList<IAnimal>- потому что я понимаю , что это помещает результаты , чтобы проверить на кучу.
  • Настройка содержимого результатов - которые я понимаю , как хорошо; но мой главное , чтобы проверить , что Zoo.Animalsвозвращается IEnumerable<IAnimal>, и даже лучше, что он использует yield returnвнутри.

Любые предложения о том, делать это лучше или проще?

Изменить: Я пытаюсь определить оптимальный способ проверить взаимодействие между IEnumerable<T>и все , что я использую. Я не пытаюсь , чтобы проверить , что Zooможет держать животное, скорее, Zooразоблачает , как IEnumerable<IAnimal>и что yield returnпривыкает , а также.

Задан 07/08/2008 в 06:58
источник пользователем
На других языках...                            


2 ответов

голоса
4

Если вы тестирование реализации , почему вы пытаетесь дразнить его в первую очередь? Почему не только CageThe (IAnimal) , а затем проверить , что животные содержит что IAnimal?

Я понимаю, что вы насмешливый IAnimals, видя, как вы, видимо, еще не имеют каких-либо конкретных животных, чтобы играть с, но почему бы не просто сделать их корешки, потому что очевидно, что вы ничего не ожидая, что происходит с ним помимо того, занесен в список?

Изменить: Что-то примерно вдоль этих линий (не проверял, не может составить, может съесть собаку и т.д.):

[TestFixture]
public class ZooTest 
{
    [Test]
    public void ZooCagesAnimals()
    {
        MockRepository mockery = new MockRepository();

        IAnimal mockLion = mockery.Stub<IAnimal>();
        IAnimal mockRhino = mockery.Stub<IAnimal>();

        IZoo zoo = new Zoo();

        zoo.CageThe(mockLion);
        zoo.CageThe(mockRhino);

        List<IAnimal> animals = new List<IAnimal>(zoo.Animals);
        Assert.IsTrue(animals.Contains(mockLion));
        Assert.IsTrue(animals.Contains(mockRhino));
    }
}
Ответил 07/08/2008 в 07:20
источник пользователем

голоса
3

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

Если вы хотите, чтобы специально проверить итератор, вы должны, вероятно,

Assert.IsNotNull(zoo.Animals);

И убедитесь, что переписчик фактически перебирает над всеми вещами, которые вы добавили в зоопарк. Что я и собирался на там. :)

Я не уверен, если это вообще возможно, чтобы проверить, если обратный выход вызываются, потому что возвращение выхода просто синтаксический сахар для сгенерированного компилятора IEnumerable. Например, вызов

zoo.Animals.GetEnumerator();

не будет выполнять любой код вы написали в счетчику. В первый раз, что происходит на первый вызов IEnumerator.MoveNext ();

Теперь, если вы пытаетесь проверить взаимодействие между бетонным зоопарком и IEnumerable содержащегося этим зоопарком, вы должны сделать IEnumerable поле на зоопарке и впрыснуть макет IEnumerable в эту область вместо реализации конкретного IEnumerable непосредственно в зоопарке.

Я надеюсь, что это какая-то помощь.

Ответил 08/08/2008 в 06:27
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more