Мокинг COM-объекта

Я работал над оболочкой для COM-объекта, которая может принимать и возвращать только строки. Интерфейс COM-объекта выглядит так:

    interface IMapinfo
    {
        void Do(string cmd);
        string Eval(string cmd);
    }

Теперь я создал классы, которые завершают основные функции следующим образом:

    public class Table 
    {
        IMapinfo MI;
        public string Name
        {
            //pass the command to the COM object and get back the name.
            get{return MI.Eval("TableInfo(1,1")");}
        }

    }

Теперь я хотел бы провести модульное тестирование этих классов без необходимости каждый раз создавать настоящий COM-объект, настраивать мир, а затем запускать тесты. Итак, я изучал использование имитационных объектов, но я немного смущен тем, как я бы использовал имитацию в этой ситуации.

Я планирую использовать Moq, поэтому я написал этот тест следующим образом:

        [Test]
        public void MockMapinfo()
        {
            Moq.Mock<Table> MockTable = new Moq.Mock<Table>();
            MockTable.ExpectGet(n => n.Name)
                .Returns("Water_Mains");

            Table table = MockTable.Object;
            var tablename = table.Name;

            Assert.AreEqual("Water_Mains", tablename,string.Format("tablename is {0}",tablename));
            Table d = new Table();
         }

Это правильный способ издеваться над моим COM-объектом? Как это утверждение верно, что строка, отправляемая в функцию eval, верна? или я все не так делаю?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 635
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это дубликат? Как мне сделать TDD с объектом COM OLE

Обновлено: Похоже, вы задаете тот же вопрос, но для проверки своего издевательского кода (OOPS).

Вы не совсем подходите для своего сценария насмешек. Вы правы, что хотите изолировать внешние зависимости, и ваш COM-объект определенно соответствует этим критериям. Хотя я не любитель moq (я предпочитаю RhinoMocks), за mocks стоит идея тестирование взаимодействия ...

Тестирование взаимодействия - это изучение того, как сплоченные наборы объектов работают вместе. Допустимым тестом в этом сценарии было бы написание теста для компонента, который зависит от поведения вашего COM-объекта.

В этом случае ваша «Таблица», которая действует как оболочка для вашего COM-объекта, также зависит от поведения COM-объекта. В качестве аргумента предположим, что ваш объект Table выполняет настраиваемую логику в отношении значений, возвращаемых вашим COM-объектом.

Теперь вы можете писать изолированные тесты для своего объекта Table, в то время как моделирование поведения вашего COM-объекта с помощью Mocks.

public class Table
{
   public Table(IMapInfo map)
   {
      _map = map;
   }

   public string Name
   {
      get 
      {
        string value = _map.Eval("myexpression");
        if (String.IsNullOrEmpty(value))
        {
            value = "none";
        }
        return value;
      }
   }

   private IMapInfo _map;
}

[TestFixture]
public class TableFixture // is this a pun?
{
   [Test]
   public void CanHandleNullsFromCOM()
   {
       MockRepository mocks = new MockRepository(); // rhino mocks, btw
       IMapInfo map = mocks.CreateMock<IMapInfo>();

       using (mocks.Record())
       {
          Expect.Call(map.Eval("myexpression").Return(null);
       }

       using (mocks.PlayBack())
       {
          Table table = new Table(map);
          Assert.AreEqual("none", table.Name, "We didn't handle nulls correctly.");
       }

       mocks.verify();
   }
}

Возможно, ваш COM-объект выдает исключения при вызове, а может быть, он не очень хорошо обрабатывает строковые выражения. На самом деле мы тестируем, как наш объект Table взаимодействует с IMapInfo без привязки к реализации COM-объекта. Мы также обеспечиваем связь между Table и IMapInfo в том смысле, что объект IMapInfo должен вызываться во время теста.

Надеюсь это поможет.

Мягкость есть, но в то время я просто использовал прямой COM-объект для передачи строк, и теперь у меня есть куча слоев, через которые проходит строка, если это имеет смысл.

Nathan W 20.11.2008 09:22

и на этот раз я больше ищу вопрос типа "это правильно", а не "если я должен использовать макеты"

Nathan W 20.11.2008 09:23

Я обновил свой ответ. Ваш пример неверен; вы утверждаете, что фиктивный фреймворк дает вам значение, которое вы ему предоставили, и оно всегда будет проходить. В моем примере показано, как проверить взаимодействие между таблицей и IMapInfo.

bryanbcook 21.11.2008 18:50

Ваш пример был бы правильным, если бы вы тестировали объект, который взаимодействовал с Table. Но просто создать макет, а затем утверждать, что он имеет заданные вами значения, - это не валидный тест.

bryanbcook 21.11.2008 18:52

Другие вопросы по теме