2012-06-07 4 views
2

С Moq, можно ли настроить издеваемое свойство так, чтобы оно мутировало?Mocking побочные эффекты

Например, если:

public interface IService // To be mocked. 
{ 
    bool IsConnected { get; } 
} 

Можно настроить макет из IService таким образом, что следующие проходы?

var mockService = new Mock<IService>(); 

// Setup mockService so IsConnected mutates...? 

bool before = mockService.Object.IsConnected; 

bool after = mockService.Object.IsConnected; 

Assert.AreNotEqual(before, after); 

Конечно, эта установка не делать трюк:

mockService.SetupGet(service => service.IsConnected).Returns(false); 
mockService.SetupGet(service => service.IsConnected).Returns(true); 

Это согласуется мое понимание того, что Moq не реализует модель записи/воспроизведения.

Вот немного более реалистичный пример:

public interface IService // To be mocked. 
{ 
    bool IsConnected { get; } 

    void Connect(); // Mutates IsConnected. 
} 

class Client // To be tested 
{ 
    private readonly IService service; 

    public Client(IService service) 
    { 
     this.service = service; 
    } 

    public bool DoWork() 
    { 
     if (!service.IsConnected) // In test, IsConnected should return false. 
     { 
      service.Connect(); 
     } 

     if (!service.IsConnected) // In test, IsConnected should return true. 
     { 
      return false; 
     } 

     // ... yada yada yada more code 

     return true; 
    } 
} 

Я использую Moq 4.0.10827.0.

+0

Вы уверены, что тестируете правильную вещь? По моему опыту, когда вы пытаетесь сделать что-то подобное, вы обычно тестируете вне сферы вашего устройства. => В этой ситуации: это импорт для ClientTest для проверки Сервиса? Разве это не должно случиться в ServiceTest? –

+0

@ Team-JoKi Хорошая точка. В идеале состояние соединения было бы предпосылкой тестов DoWork. Идеально. – Watsontap

ответ

3

Вы можете установить Returns на Func<bool> вместо bool. Тогда вы должны написать такую ​​функцию, чтобы она меняла свой результат. Что-то вроде ....

bool isConnected = false 
var mockService = new Mock<IService>(); 
// Setup mockService so IsConnected mutates...? 
mockService.Setup(s => s.Connect()).Callback(() => isConnected = true); 
mockService.SetupGet(s => s.IsConnected).Returns(() => isConnected); 

bool before = mockService.Object.IsConnected; 

mockService.Object.Connect(); 

bool after = mockService.Object.IsConnected; 

Assert.AreNotEqual(before, after); 

Однако, в зависимости от того, насколько сложна ваша имя_службы получает, вы можете рассмотреть вопрос о принятии FakeService и использовать его вместо насмешки.

+0

Я действительно начал с FakeService, но потом решил попробовать его с макетом, который привел меня сюда. Благодарю. – Watsontap

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