2010-01-27 53 views
2

与昨天的question相关。我实施了Mehrdad Afshari建议的solution,但这造成了另一个问题。 回顾:我有一个包含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(); 
} 

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

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

不幸的是动物的由Rhino Mocks创建的类型是动物代理和我所要求的动物,它打破我的测试。有关如何纠正这种情况的任何建议?

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

+0

你可以发布你的测试代码吗? – 2010-01-27 09:42:02

+0

就在那里。 – Johnny 2010-01-27 10:18:37

回答

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

我认为不是。如果你想做你所概述的事情,我认为你将不得不创造一个真正的动物而不是模拟。

+0

其实你的第一个建议是行不通的,因为编译器必须知道在执行之前我在'zoo.GetAnimalsOfType ()'中请求哪个类型并且使用'zoo.GetAnimalsOfType ()'类型不能事先知道。 – Johnny 2010-01-27 09:58:00

+0

那么我认为你坚持使用一个真正的动物或滚动自己的模拟和使用的类型。我会编辑答案。 – 2010-01-27 10:04:56

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

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

一般来说,我倾向于避免在类型上键入集合,所以我没有这些问题(例如,我有一个返回枚举的类的属性等)。