2010-10-27 2 views
14

У меня есть следующий класс:Moq: настройка свойства без сеттера?

public class PairOfDice 
{ 
    private Dice d1,d2; 
    public int Value 
    { 
     get { return d1.Value + d2.Value; } 
    } 
} 

Теперь я хотел бы использовать в моем тесте, который возвращает значение 1 в PairOfDice, хотя я использую случайные значения в моих реальных кубиков:

[Test] 
public void DoOneStep() 
{ 
    var mock = new Mock<PairOfDice>(); 
    mock.Setup(x => x.Value).Return(2); 
    PairOfDice d = mock.Object; 
    Assert.AreEqual(1, d.Value); 
} 

К сожалению, я получите ошибку Invalid setup on non-overridable member. Что я могу сделать в этой ситуации?

Обратите внимание, что это моя первая попытка реализовать Unit-Tests.

ответ

12

Ваша проблема в том, что это не virtual. Не потому, что у вас нет сеттера.

Moq не может создать прокси-сервер, потому что он не может переопределить ваше свойство. Вам нужно либо использовать интерфейс, виртуальный метод, либо абстрактный метод.

+0

Есть ли недостаток, устанавливающий это свойство в виртуальном? – Sven

+2

Только если вы рассматриваете подклассы 'override'-ing, которые используют риск. В принципе ничего примечательного, если это супер-безопасная функция, вы не можете доверять другим классам, чтобы получить право, однако те, которые вы не должны издеваться, так как они не будут публичными. – Aren

+2

Этот ответ теперь устарел, так как Moq способен высмеивать не виртуальные свойства. – krillgar

36

Вы можете использовать .SetupGet на своем макетном объекте.

например.

[Test] 
public void DoOneStep() 
{ 
    var mock = new Mock<PairOfDice>(); 
    mock.SetupGet(x => x.Value).Returns(1); 
    PairOfDice d = mock.Object; 
    Assert.AreEqual(1, d.Value); 
} 

Для получения дополнительной информации см. here.

+2

Все еще имеет точно такую ​​же проблему, как упоминалось выше, проблема в том, что она не является виртуальной. –

+3

SetupGet - правильный метод, независимо от того, правильный ответ. Создание виртуального поля, которое НИКОГДА не будет переопределено или не будет нуждаться, является простым глупым и может нарушать то, что разработчик хочет защитить. Это простая проблема, и виртуальное поле, вероятно, мало влияет, но в реальном мире, делая что-то виртуальное, просто чтобы вы могли проверить, что это неверно, вот почему вы МОГУ ИЗМЕНИТЬ значение, используя SetupGet. – iGanja

+0

@Jim, теперь ваша ссылка идет на 404, есть ли способ ее обновить? +1 по той же причине, о которой упоминает iGanja. –

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