代码之家  ›  专栏  ›  技术社区  ›  Johnny

Rhino模拟存根返回与预期不同的类型,并破坏了我的单元测试

  •  2
  • Johnny  · 技术社区  · 16 年前

    question . 我实现了 solution 提议人 Mehrdad Afshari 但这又引发了另一个问题。 总而言之:我有一个类,其中包含一个 Type->IList<Type> 例如 Cat->{cat1, cat2}, Zebra->{zebra1, zebra2} 哪里 Cat Zebra 是的子类 Animal . 现在 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));  
    

    不幸的是,这种动物是由

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

    2 回复  |  直到 5 年前
        1
  •  1
  •   Sam Holder Brian Adams    16 年前

    由于编译器需要提前知道类型,因此无法使用此选项:

    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.AreName()

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

    我想不会吧。如果你想做你概述的事情,我认为你必须创造一个真实的动物,而不是一个模仿者。

        2
  •  2
  •   Grzenio    16 年前

    您可以要求输入刚才插入的特定类型。您必须创建一个助手函数:

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

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