2013-11-12 2 views
1

Возможно ли использовать moq и переопределить конструктор с библиотекой Moq?Как мок и переопределить конструктор?

У меня есть класс, как это:

public class A{ 
    private string _b; 
    public A() 
    { 
     _b = Service.getB(); 
    } 
    public int duplicate(int a){ 
     return a*2; 
    } 
} 

Я хочу проверить метод «дублировать», но я не могу создать экземпляр объекта типа А, потому что не хватает некоторых зависимостей. Могу ли я как-то переопределить/mock конструктор, чтобы создать объект и использовать его для тестирования других методов?

Изменения должны применяться только в тесте, Я не должен менять класс A.

+5

Лучший дизайн (субъективно) заключается в том, чтобы внедрить вашу зависимость от Сервиса в конструктор. Тогда намного проще выполнить единичный тест (потому что вы можете легко высмеять 'Service.getB()'). – EkoostikMartin

+0

Я предполагаю, что для такого случая нет решения. Благодаря! – gradosevic

ответ

1

Так что же такое Service? Лучшим вариантом было бы поместить это как параметр в конструктор. Затем вы можете издеваться над этим и уметь тестировать свой метод duplicate без каких-либо жестко закодированных зависимостей.

+0

Да, я знаю об этом, но, к сожалению, я не могу изменить класс в этом случае. Я просто хочу знать, можно ли это проверить или нет. – gradosevic

-1

Если я правильно понял, что вы можете сделать, это создать новый конструктор внутреннего

internal A(B b) 
    { 
     _b = b; 
    } 

так что вы не измените свой публичный API для других сборок, и в тестовой сборке добавить атрибут assembly.cs

[InternalsVisibleTo("YourTestAssembleNamespace.TestClass.dll")] 

так в тесте вы могли бы сделать что-то вроде этого

//bmock = new Mock<IB>(); 
var A = new A(bmock); 
+0

Это может быть решением, если я могу изменить класс A, но не в этом случае – gradosevic

+0

Я не согласен с этим решением. Вы никогда не должны изменять свой основной код JUST для проверки.Вместо этого вы должны писать код с учетом тестирования, когда он имеет смысл в вашем дизайне и архитектуре. – EkoostikMartin

+1

@EkoostikMartin Согласитесь с тем, что основной код не следует изменять, но в некоторых случаях, если логика не изменяется и только разрешает инъекцию зависимостей (даже при низкой плотности вливания зависимостей) - это изменение для поддержки тестирования, это может быть решение –

2

Th ere нет возможности переопределить или издеваться над конструктором, используя Moq framework.

Даже если вы попытаетесь создать класс TestA и наследуете его от A, в любом случае будет вызываться беззадачный конструктор. Подробнее вы можете прочитать в следующей статье "Constructors in C#". Существует также цитата из MSDN:

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

Если это действительно необходимо, чтобы переопределить конструктор вы можете взглянуть на другую рамке Mocking (например TypeMock могут высмеивать даже статические конструктор)

Есть SO question "What C# mocking framework to use?" с длинным списком насмешливых рамок и презентациями "Battle of the mocking frameworks" что может помочь вам выбрать правильный инструмент.

+0

@argonius, если вы действительно не можете изменить класс, который вы пытаетесь проверить, тогда это лучший ответ. Вам понадобится насмешливая структура, которая использует отражение для перехвата вызовов. Это будет гораздо более тяжелое решение, чем если бы вы могли просто обеспечить переопределение конструктора, чтобы позволить инъекцию, но это звучит так, будто это может быть ваш единственный выбор. Мне тебя жаль. :-D – Damon

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