2013-04-15 2 views
2

Возможно ли издеваться над оператором is? В моем коде у меня есть логика в зависимости от того, какой тип класса он есть, но само значение хранится в классе как общий интерфейс.Mock является оператором

В общем, что я хочу сделать, это вернуть true, определяя издеваться, чтобы быть IValue, но вернуться true для is Value

public class Value : IValue 
{ 
} 

public interface IValue 
{ 
} 
public class Tester 
{ 
    public bool CheckIfValue(IValue value) 
    { 
     return value is Value; 
    } 
} 

[Test] 
public void TestIfValue() 
{ 
    Tester tester = new Tester(); 

    var value = MockRepository.GenerateStub<IValue>(); 
    // can I add anything here which will make CheckIfValue return true? 

    bool isValue = tester.CheckIfValue(value); 
    Assert.That(isValue, Is.True); 
} 
+0

Does 'MockRepository.GenerateStub ()' возвращает реализацию IValue, которая не является «значением»? – ken2k

+0

@ ken2k - да, он создаст класс во время выполнения, который реализует этот интерфейс с использованием рамки Castle.DynamicProxy. –

ответ

6

Нет, это не представляется возможным «фиктивный» оператор is, is будет возвращается только в следующих случаях:

  1. Проверяемый объект является экземпляром проверяемого типа.
  2. Проверяемый объект является подклассом проверяемого типа.
  3. Проверяемый объект реализует проверяемый тип интерфейса.

Ваша конструкция плохо, вы не должны требовать каких-либо IValue если вы на самом деле нужно, чтобы быть экземпляром Value.

Суть заключается в том, чтобы зависеть от абстракций, а не от реализации, поэтому у вас есть интерфейс IValue. Tester не должно заботиться о том, получает ли он Value, MockValue или что-то еще, он должен просто зависеть от методов и свойств, определенных в интерфейсе IValue.

Дело в создании издеваться, чтобы проверить поведение вашего Tester класса в конкретном случае, макет позволяет определить поведение объекта Tester получает для этого теста без необходимости создавать множество фиктивных классов, такие как class FakeValueWhichDoes... : IValue, чтобы проверить его.

+0

+1, соглашайтесь на плохой дизайн. Вся цель интерфейсов - НЕ использовать фактическую реализацию. Если параметр имеет тип IValue, тогда весь блок кода должен ТОЛЬКО использовать то, что выставлено IValue. – ken2k

+2

Ваши три случая являются неполными FYI. Например, 'object o = (Func ) (() =>" "); bool b = o - Func ; 'возвращает true, но не соответствует ни одному из ваших трех случаев. –

+0

@EricLippert благодарит за это, я забыл упомянуть Ковариацию. –

Смежные вопросы