Заглушка Rhino Mock возвращает тип, отличный от ожидаемого, и нарушает мой юнит-тест - PullRequest
2 голосов
/ 27 января 2010

Относится к вчерашнему вопросу . Я реализовал решение , предложенное Мехрдадом Афшари , но это вызвало еще одну проблему. Напомним: у меня есть класс, содержащий словарь 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));  

К сожалению, тип животного, созданного Rhino Mocks , является прокси животного, и я спрашиваю Animal, который нарушает мой тест. Любые предложения о том, как исправить ситуацию?

Обновление: спасибо всем за решения.

Ответы [ 2 ]

2 голосов
/ 27 января 2010

Вы можете запросить конкретный тип, который вы только что вставили. Вы должны создать вспомогательную функцию:

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 голос
/ 27 января 2010

Поскольку вы не можете использовать это из-за того, что компилятору нужно знать тип заранее:

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

Полагаю, нет. Если вы хотите сделать то, что вы обрисовали в общих чертах, я думаю, вам придется создать настоящее животное, а не издевательство.

...