Заглушка свойства, которое находится в конкретном классе, но не в интерфейсе для модульного тестирования

#c# #unit-testing #mocking #mef #rhino-mocks

#c# #модульное тестирование #издевательство #mef #rhino-издевается

Вопрос:

У меня есть класс, который содержит больше информации, чем мой интерфейс. У него есть свойство, которое я не раскрывал в своем интерфейсе.

  public interface IViewResolver
{
    object GetViewFor(string viewName);

}
  

Теперь я хочу реализовать MefViewResolver на основе этого интерфейса.

 public class ViewResolver : IViewResolver
{


    [ImportMany]
    public IEnumerable<Lazy<IView,IViewMetaData>> Views { get; set; }



    public object GetViewFor(string viewName)
    {
        var view = Views.Where(x => x.Metadata.Name == viewName).FirstOrDefault();

        return view == null ? null : view.Value;
    }

}
  

Мой SUT получает IResolver для каждой инъекции конструктора, загруженной моим mefViewResolver. В моем модульном тестировании я хотел бы предварительно установить свойство Views извне, не используя mef или не будучи специфичным для mef в моем интерфейсе.
По сути, я хочу задать представления с ожидаемым значением и посмотреть, возвращает ли моя viewmodel, которая использует IViewResolver, предустановленное представление…
Как я могу заглушить свойство views, даже если оно не существует в моем интерфейсе…

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

Спасибо D.

Ответ №1:

Если вы хотите протестировать свою ViewModel (а не распознаватель), который знает только интерфейс IViewResolver, у вас не должно возникнуть никаких проблем: единственный метод (в соответствии с предоставленным кодом), к которому ViewModel может получить доступ, это GetViewFor . Все, что вам нужно сделать, это вернуть соответствующее представление для каждого тестового примера с учетом имени представления. В RhinoMocks это должно быть что-то вроде:

 // Arrange the test objects
var viewResolverMock = MockRepository.GenerateMock<IViewResolver>();
viewResolverMock.Stub(x => x. GetViewFor(thisTestViewName).Return(thisTestView);
var myViewModel = new MyViewModel(viewResolverMock);

// Do the actual operation on your tested object (the view model)
var actualResult = myViewModel.DoSomethingWithTheView();

// Assert 
AssertAreEqual(expectedResult, actualResult);
  

Комментарии:

1. Возможно, вам захочется Stub вызвать viewResolverMock.GetViewFor(…) вместо создания ожидания, поскольку это всего лишь запрос, и у вас есть утверждение для результата из MyViewModel . DoSometingWithTheView(), который, как предполагается, зависит от IViewResolver.

2. Спасибо за предупреждение. Я пытаюсь протестировать 2 мысли одновременно. Я должен самостоятельно протестировать свой mefviewresolver и должен полагаться на то, что он работает в моем тесте модели представления. Благодаря этому я могу без проблем заглушить свой GetViewFor… Еще раз спасибо =)