Rhino Mock存根返回与预期不同的类型并打破我的单元测试

时间:2010-01-27 09:33:15

标签: c# unit-testing rhino-mocks

与昨天的question相关。我实施了solution提出的Mehrdad Afshari,但这又引发了另一个问题。 回顾一下:我有一个包含Type->IList<Type>字典的类,例如Cat->{cat1, cat2}, Zebra->{zebra1, zebra2}其中CatZebraAnimal的子类。现在Mehrdad提出了以下方法来检索某种类型的所有动物:

IList<T> GetAnimalsOfType<T>() where T : Animal {
    return dictionary[typeof(T)].OfType<T>().ToList();
}

这可行,但打破了我的单元测试。原因是Animal是一个抽象类,因此我使用Rhino Mocks来存根(使用animal = MockRepository.GenerateStub<Animal>();)。我对这个类的单元测试试图创建一个新的动物,然后看它是否包含在字典中。

zoo.AddAnimal(animal);  
IList<Animal> animals= zoo.GetAnimalsOfType<Animal>();  
Assert.That(animals[0], Is.EqualTo(animal));  

不幸的是Rhino Mocks创造的动物类型是一个动物代理,我要求动物,这打破了我的考验。关于如何纠正这种情况的任何建议?

更新:感谢所有解决方案。

2 个答案:

答案 0 :(得分:2)

您可以询问刚刚插入的特定类型。你必须创建一个辅助函数:

T Get<T>(T parameterOnlyToInferTheType)
{
    IList<Animal> animals= zoo.GetAnimalsOfType<T>();  
    return animals[0];
}

animal = MockRepository.GenerateStub<Animal>();
zoo.AddAnimal(animal);  
Animal expected = Get(animal);
Assert.That(expected, Is.EqualTo(animal)); 

看起来有点狡猾,但应该工作。

一般情况下,我倾向于避免在类型上键入集合,因此我没有这些问题(例如,我在类上返回枚举的属性等)。

答案 1 :(得分:1)

由于编译器需要事先知道类型,因此您无法使用它:

zoo.AddAnimal(animal);  
IList<Animal> animals= zoo.GetAnimalsOfType<typeof(animal)>();  
Assert.That(animals[0], Is.EqualTo(animal));

我认为你必须推出自己的模拟:

class MockAnimal : Animal
{
}

zoo.AddAnimal(new MockAnimal());  
IList<Animal> animals= zoo.GetAnimalsOfType<MockAnimal>();  
Assert.That(animals[0], Is.EqualTo(animal));

您也不想检查返回的实例是否与添加的实例不同,而不仅仅是等于? (不是确定的语法,仍然是Asset.AreSame())

Assert.That(animals[0], Is.SameAs(animal));

其他并不令人惊讶,因为你希望GetAnimalsOfType只返回确切类型的动物不是你,而不是那些衍生出来的类型?如果你这样做了:

class Tiger : Animal
{
}

zoo.AddAnimal(new Tiger());  
IList<Animal> animals= zoo.GetAnimalsOfType<Animal>();

你希望这会通过:

Assert.AreEqual(1, animals.Count);

我假设没有。如果你想做你概述的事情,我想你必须创建一个真正的动物而不是模拟。