Как избежать динамического использования при издевательстве в Excel.workheet?

Я пытаюсь высмеять электронную таблицу Excel, используя NSubstitute или другую насмешливую структуру и MSTest (Visual Studio 2010). Я не уверен, есть ли лучший способ, чем это - и это не совсем работает для тестирования:

Вот пример (это все прототип кода прямо сейчас и не очень чистый):

int[] lowerBounds = { 1, 1 };
int[] lengths = { 2, 2 };

//Initialize a 1-based array like Excel does:
object[,] values = (object[,])Array.CreateInstance(typeof(object), lengths, lowerBounds);
values[1,1] = "hello";
values[2,1] = "world";      

//Mock the UsedRange.Value2 property
sheet.UsedRange.Value2.Returns(values); 

//Test:   
GetSetting(sheet, "hello").Should().Be("world");  //FluentAssertions

До сих пор так хорошо: это проходит, если метод GetSetting в том же проекте как мой тест. Однако, когда GetSetting находится в моем проекте VSTO Excel-Addin, он не работает со следующей ошибкой в ​​первой строке функции GetSetting:

System.MissingMethodException: Error: Missing method 'instance object [MyExcel.AddIn] Microsoft.Office.Interop.Excel.Range::get_Value2()' from class 'Castle.Proxies.RangeProxy'.

Для справки GetSetting захватывает значение из столбца A в листе и возвращает значение в столбце B.

public static string GetSetting(Excel.Worksheet sheet, string settingName) {
  object[,] value = sheet.UsedRange.Value2 as object[,];
  for (int row = 1; row <= value.GetLength(1); row++) {
    if (value[1, row].ToString() == settingName)
      return value[2, row].ToString();
  }
  return "";
}

Последний интересный фрагмент - если я переопределю подпись моего метода следующим образом:
публичная статическая строка GetSetting ( динамический лист, строка settingName)
он работает в проекте VSTO.

Итак, что происходит, и что лучший способ сделать что-то подобное?

Спасибо!

Ответ 1

Обновление VS2012: Типы Moq и Interop: работает в VS2012, не работает VS2010?

Сначала: что-то изменилось: Как избежать использования динамического при издевательстве в Excel.workheet?

Я столкнулся с той же проблемой, что и Mocking Excel, используя NSubstitute. Динамика разрешила проблему так же, как вы упоминаете. Однако я хотел найти основную причину.


Когда ваш проект имеет ссылку на Microsoft.Office.Interop.Excel.Extensions.dll, вам нужно проверить, видимо ли свойство Embed Interop Types. Если это означает, что ваш таргетинг .Net 4.0 (что я могу угадать из ключевого слова dynamic).

Вы можете оставить тестовый проект таргетинг .NET 4.0, но вам нужно изменить проект VSTO Project.Net обратно до 3.5. Тогда вы будете вероятно, придется сделать какое-то явное литье и полностью избавиться от этих ошибок:

Объект С# Office Excel Interop "не содержит определения для" errors, вот несколько примеров:

.Net 4.0:

if (tmpsheetName == xlApp.ActiveSheet.Name)

.Net 3.5 эквивалент

Worksheet activeSheet = (Worksheet)xlApp.ActiveSheet;
if (tmpsheetName == activeSheet.Name)

Другой пример:

rn.Select();

.Net 4.0

xlApp.Selection.HorizontalAlignment = Constants.xlCenter; 
xlApp.Selection.Font.Bold = true;
xlApp.Selection.Merge();

.Net 3.5 эквивалент

rn.HorizontalAlignment = Constants.xlCenter;
rn.Font.Bold = true;
rn.Merge();

Приступайте к исправлению всех синтаксических ошибок .Net 3.5 vs 4.0 в соответствии с приведенными выше примерами. Не забывайте удалить тип параметра dynamic и заменить его оригиналом Worksheet. Наконец, снова запустите тест, и он пройдет!!!

Учитывая все горе, которое я испытал с Microsoft.CSharp.DLL в этом потоке, я считаю, что тестирование VSTO.Net 4.0 проектов с Mocking Frameworks не работает.

Ответ 2

Оказывается, что высмеивание очень сложных объектов COM-взаимодействия, таких как объект Excel или объект InDesign, с использованием любой из основанных на замке фреймворков (nsubstitute, ninject и т.д.) не обеспечивает достаточной загрузки производительности. Время работы для тестов по-прежнему измеряется в секундах. (Умножая это на десятки или сотни тестов, тесты модулей все еще слишком медленны, чтобы работать в соответствии с принципами TDD тестирования постоянно.)

Тестирование логики Excel затем следует считать интеграционным тестом, и, таким образом, работа с фактическим объектом Excel должна быть прекрасной, что делает насмешливым не очень полезным в таком сценарии. Результаты будут гораздо более полезными для тестирования фактического объекта.

Тестирование уровня абстракции, помещенного между Excel и приложением, позволит быстро протестировать логику приложения. И тестирование уровня абстракции для улучшения при тестировании интеграции должно быть достаточным для тщательной проверки приложения.