2008-08-07 12 views
5

내 최근의 재앙이 조롱을 당하면서 실제로 모의 객체 IEnumerable<T>에 결과를 밀어 넣을 필요가 없습니다. 여기 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.AnimalsIEnumerable<IAnimal>을 반환하고 더 나아가 그 안에 yield return을 사용하고 있음을 테스트하는 것입니다.

더 나은 방법과 간단한 방법에 대한 제안 사항이 있으십니까?

편집 : 나는 IEnumerable<T>과 내가 사용하는 모든 것의 상호 작용을 테스트하는 최적의 방법을 결정하려고합니다. 나는 Zoo이 동물을 수용 할 수 있다는 것을 테스트하려하지 않고, ZooIEnumerable<IAnimal>으로 표시되며, yield return도 사용되는 것으로 나타났습니다.

+1

돌이켜 볼 때이 메시지는 ** 끔찍한 ** 질문입니다. 투표를 닫으려고하는 중 –

답변

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

내가 당신을 아주 에 기대에 모의 기대치를 설정하는 방법을 볼 수 없습니다 : 약이 라인을 따라 뭔가 (테스트되지는 당신의 개 등을 먹을 수있다, 컴파일하지 않을 수 있습니다) 모의 객체가 아닌 객체. 또한 컴파일러가 반복자를 생성 할 때 실제로 발생하지 않는 IList를 반환 할 것을 기대하고 있습니다.

특별히 반복자를 테스트하려면

, 당신이해야 아마

Assert.IsNotNull(zoo.Animals); 

그리고 열거 실제로 당신이 동물원에 추가 된 모든 것들에 걸쳐 열거 있는지 확인합니다. 내가 그곳에 간 것은 무엇인가. :)

수익률 반환은 컴파일러에서 생성 된 IEnumerable의 문법적 설탕이기 때문에 수익률 반환이 호출되는지 테스트 할 수 있는지 확실하지 않습니다. 예를 들어,

zoo.Animals.GetEnumerator(); 

을 호출하면 열거 자에 기록한 코드가 실행되지 않습니다. 처음 발생하는 것은 IEnumerator에 대한 첫 번째 호출에서 발생합니다.MoveNext();

콘크리트 동물원과 그 동물원에 포함 된 IEnumerable 간의 상호 작용을 테스트하려는 경우, 동물원에 IEnumerable 필드를 만들고 구체적인 IEnumerable을 구현하는 대신 해당 필드에 모의 IEnumerable을 주입해야합니다 동물원에서 직접.

도움이 되었기를 바랍니다.

관련 문제