Индексатор Range
возвращает динамический объект, это источник вашей проблемы.
Moq использует Castle Dynamic proxy
для генерации поддельных объектов, Castle.Proxies.RangeProxy
- это сгенерированный класс в вашем случае.Так как этот объект не является COM
объектом, вызывается обработка тех, что связыватель времени выполнения C #.Связыватель времени выполнения разрешает тип и ищет метод индексатора, но ему не удалось разрешить его, потому что у сгенерированного класса его нет.
Самый простой способ решить ваш вопрос - вернуть результат индексатора в строгийRange
локальная переменная:
Тогда ваш тест не пройден, поскольку range.Rows[1]
равно row1
...
Поэтому измените свой тестовый код на:
[TestMethod]
public void MockRowsTest()
{
var row1 = MockUtils.MockCells("test_row_1", "test_row_1");
var row2 = MockUtils.MockCells("test_row_2", "test_row_2");
var range = MockUtils.MockRows(row1, row2);
Assert.IsNotNull(range);
Assert.AreEqual(2, range.Count);
Assert.IsNotNull(range.Rows);
Assert.AreEqual(2, range.Rows.Count);
Range x = range.Rows[1];
Range y = range.Rows[2];
var xCell = x.Cells[1];
var yCell = y.Cells[1];
Assert.AreSame(row1, x);
Assert.AreSame(row2, y);
Assert.AreEqual("test_row_1", xCell.Value2);
Assert.AreEqual("test_row_2", yCell.Value2);
}
Приведенный выше UT пройдет тест.IMO, вам следует разбивать вызовы агрегации на «атомарные OPS (многострочные) и методы» не потому, что он пройдет тест, потому что он сделает ваш код дружественным к отладке кодом (я называю это «11-е правило», где ваш код)будет прочитан еще как минимум 10 раз с момента его написания ... Итак, позвольте компилятору удалить транзитивные локальные переменные и сделать его дружественным для отладки кодом ..).
Здесь выможете прочитать простое и краткое объяснение со ссылками на то, как динамически работает в c #.
Здесь вы можете прочитать больше о Castle Dynamic Proxy.
BTW;Вы также можете сделать:
Range x = range.Rows[1].Cells;
var str = x[1].Value2;
, чтобы получить значение