Jak si správně zesměšňovat je IEnumerable <T>?

hlasů
6

Můj poslední havárii klopýtají posmívání není grokking že musím skutečně tlačit výsledky uvnitř makety objektu IEnumerable<T>.

Zde je ukázka (ukázka pouze IEnumerable<T>, není vlastně dobrá testování interakce založené!):

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

Nelíbí se mi, jak jsem se dostal do práce z následujících důvodů:

  • Konzumace IEnumerable<IAnimal>výsledky do IList<IAnimal>- protože chápu to dává výsledky ověřit na haldy.
  • Nastavení obsahu výsledků - což chápu stejně; ale můj hlavní je otestovat, zda Zoo.Animalsse vrací IEnumerable<IAnimal>, a ještě lépe, že je používán yield returndovnitř.

Nějaké návrhy na dělá to lepší nebo jednodušší?

Edit: Snažím se určit optimální způsob, jak otestovat interakci mezi IEnumerable<T>a cokoliv jsem pomocí. Nesnažím se otestovat, zda Zoomůže držet zvířata, spíše to, že Zooodhaluje, jak IEnumerable<IAnimal>a který yield returnje stále používán také.

Položena 07/08/2008 v 06:58
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
4

Pokud testujete na realizaci , proč se snažíte zesměšňovat ji na prvním místě? Proč ne jen klecFixační (IAnimal) a pak zkontrolujte, zda je zvíře obsahuje že IAnimal?

Mám že jste zesměšňovat IAnimals, když viděl, jak je vidět, Vy ještě nemáte žádné konkrétní zvířata na hraní, ale proč ne jen aby jim pahýly, protože samozřejmě nejste nic jiného očekával, že se s nimi stane na rozdíl od bytí do seznamu?

Edit: Něco hrubě podél těchto linek (nebyly testovány, nemusí kompilovat, může sníst svého psa atd):

[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));
    }
}
Odpovězeno 07/08/2008 v 07:20
zdroj uživatelem

hlasů
3

Nevím přesně, jak můžete očekávat nastavit falešné očekávání na objekt, který není falešný začít. Také jste nastavení očekávání vrátit IList, který není opravdu to, co se stane, když kompilátor generuje iterátor.

Chcete-li výslovně testovat iterátor, měli byste nejspíš

Assert.IsNotNull(zoo.Animals);

A poté ověřte, zda skutečně výčtu výčet přes všechny věci, které jste přidali do zoo. Což je to, co se děje tam uvedená. :)

Nejsem si jistý, jestli je to vůbec možné otestovat, zda výnos výnos je volána, protože výnos výnos je jen syntaktický cukr pro kompilátoru generované IEnumerable. Například volání

zoo.Animals.GetEnumerator();

neprovede některý z kódu, který napsal ve výčtu. To poprvé, co se děje, je na první výzvu k IEnumerator.MoveNext ();

Nyní, pokud se snažíte k testování interakce mezi betonovou Zoo a IEnumerable obsažené tímto Zoo, měli byste se IEnumerable pole na zoo a aplikujte falešný IEnumerable do tohoto pole namísto provádění konkrétní IEnumerable přímo v zoologické zahradě.

Doufám, že se jedná o nějakou pomoc.

Odpovězeno 08/08/2008 v 06:27
zdroj uživatelem

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