Дразнить COM-объект - PullRequest
       13

Дразнить COM-объект

2 голосов
/ 20 ноября 2008

Я работал над оболочкой для 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, верна? или я все делаю не так?

1 Ответ

3 голосов
/ 20 ноября 2008

Это дубликат? Как бы я сделал 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 должен вызываться во время теста.

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

...