2014-01-04 4 views
6

У меня есть класс, который содержит общедоступный метод, который опирается на внутренний метод, чтобы правильно вернуть его значение.Частичный издевательский внутренний метод класса с Moq

Давайте рассмотрим следующий класс и тестовый файл:

public class ClassUnderTest 
{ 
    public string NotMockedPublicMethod() 
    { 
     return MockedMethod(); 
    } 

    virtual public string MockedMethod() 
    { 
     return "original"; 
    } 
} 

Следующий тест будет работать:

var mock = new Mock<ClassUnderTest> { CallBase = true }; 
mock.Setup(m => m.MockedMethod()).Returns("mocked"); 

Assert.AreEqual("mocked", mock.Object.NotMockedPublicMethod()); 

Но давайте говорить об этом MockedMethod() мой не имеет утилиту извне. Проблема заключается в том, что маркировка этот метод как internal (даже при использовании InternalsVisibleTo() правильно):

virtual internal string MockedMethod() 

сделает точно такой же тест завершается с сообщением Assert.AreEqual failed. Expected:<mocked>. Actual:<original>.

Это ошибка Moq или некоторые ограничения?

+0

Проверить этот пост: http://stackoverflow.com/questions/1458300/moq-how-do-you-test-internal-methods – Blindsniper

+0

Thx @Blindsniper, но моя проблема не об издевательстве «внутреннего» метода просто. Как я уже сказал, я использовал директиву InternalsVisibleTo, но по какой-то причине тест останавливается после изменения его внутреннего. –

+0

Похоже, он должен работать. Вы не получаете от Мока исключения из-за насмешки недосягаемого члена? Тогда 'Setup' должен работать. Что произойдет, если вы не установите 'CallBase = true'? –

ответ

12

Это не ошибка или ограничение. Ваш тест терпит неудачу после того, как внутренний метод (даже после добавления InternalsVisibleTo), потому что он не вызывает метод издевательства, а вызывает фактический метод.

Вам нужно добавить InternalsVisibleTo для DynamicProxyGenAssembly2, а также в соответствии с ниже URL.

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

http://www.blackwasp.co.uk/MoqInternals.aspx

адреса URL не обеспечивает надлежащего объяснения, но здесь это:

Moq использует DynamicProxy Замок проекта для создания прокси на лету во время выполнения, так что члены объекта могут быть перехвачены без изменения кода класса. Вот как Moq возвращает значение, указанное в разделе "Настройка() Возвращает." (Строка "издевались" в вашем случае)

Dynamic Proxy URL:http://www.castleproject.org/projects/dynamicproxy/

Я смотрел на исходный код (см URL ниже) для DynamicProxy, и я вижу, что он использует «DynamicProxyGenAssembly2» в качестве имени сборки для сгенерированной сборки, и поэтому вам нужно добавить InternalsVisibleTo для DynamicProxyGenAssembly2.

public static readonly String DEFAULT_ASSEMBLY_NAME = "DynamicProxyGenAssembly2"; 

https://github.com/castleproject/Castle.DynamicProxy-READONLY/blob/ed8663b23a54bed641e5f97e39a6bc16fe0d976f/src/Castle.DynamicProxy/ModuleScope.cs

+0

Отлично!Я думал, что должен отмечать это только на тестовом собрании, но ваше объяснение просветил меня! Теперь ясно. Спасибо. –

Смежные вопросы