Я предположил, что MOQ автоматически создаст Mocks для любых вложенных зависимостей.Mock вложенные зависимости с MOQ
Я блок тестирования MVC контроллер ASP.Net:
public class TransactionController : Controller
{
private readonly ITransactionService _transactionService;
private readonly SearchPanelVmBuilder _searchPanelVmBuilder;
private readonly TransactionVmsBuilder _transactionVmsBuilder;
public TransactionController(TransactionVmsBuilder transactionVmsBuilder, ITransactionService transactionService, SearchPanelVmBuilder searchPanelVmBuilder)
{
_transactionVmsBuilder = transactionVmsBuilder;
_transactionService = transactionService;
_searchPanelVmBuilder = searchPanelVmBuilder;
}
// other methods omitted for brevity
public PartialViewResult SearchPanel()
{
var vm = _searchPanelVmBuilder.BuildVm();
return PartialView("_SearchPanel", vm);
}
}
Блок тестовый код:
[Fact]
public void SeachPanel_Calls_BuildSearchPanelVm()
{
// Arrange
var mockTransService = new Mock<ITransactionService>();
var mockTransVmsBuilder = new Mock<TransactionVmsBuilder>();
var mockSearchPanelVmBuilder = new Mock<SearchPanelVmBuilder>();
var controller = new TransactionController(mockTransVmsBuilder.Object, mockTransService.Object, mockSearchPanelVmBuilder.Object);
// Act
controller.SearchPanel();
// Assert
mockSearchPanelVmBuilder.Verify(x => x.BuildVm());
}
MOQ жалуется:
Невозможно создать прокси класса: MCIP.Web.UI.ViewModelBuilders.Singular.SearchPanelVmBuilder. Не удалось найти конструктор без параметров.
Класс не может создать экземпляр прокси для:
public class SearchPanelVmBuilder
{
private readonly ITransactionTypeService _transactionTypeService;
private readonly TransactionTypeVmBuilder _transactionTypeVmBuilder;
private readonly UserProvider _userProvider;
public SearchPanelVmBuilder(
UserProvider userProvider,
ITransactionTypeService transactionTypeService,
TransactionTypeVmBuilder transactionTypeVmBuilder
)
{
_userProvider = userProvider;
_transactionTypeService = transactionTypeService;
_transactionTypeVmBuilder = transactionTypeVmBuilder;
}
public virtual SearchPanelVm BuildVm()
{
return new SearchPanelVm
{
Userlist = _userProvider.GetOperators(),
TransactionTypes =
_transactionTypeService.GetAll().Select(x => _transactionTypeVmBuilder.BuildVmFromModel(x)).ToList()
};
}
}
его соответствующих зависимостей:
public class UserProvider
{
private static int retryCount;
public virtual List<string> GetOperators()...
public virtual List<string> GetGroupsForUser(WindowsIdentity identity)...
}
public interface ITransactionTypeService
{
List<TransactionType> GetAll();
}
public class TransactionTypeVmBuilder
{
public virtual TransactionTypeVm BuildVmFromModel(TransactionType transactionType)...
}
я делаю что-то не так?
Должен ли я явно указывать MOQ, чтобы идти в авто-насмешливых вложенных зависимостях?
Или я должен явно настроить вложенную Mocks - как это:
var mockUserProvider = new Mock<UserProvider>();
var mockTransTypeService = new Mock<ITransactionTypeService>();
var mockTransactionTypeVmBuilder = new Mock<TransactionTypeVmBuilder>();
var mockSearchPanelVmBuilder = new Mock<SearchPanelVmBuilder>(mockUserProvider.Object, mockTransTypeService.Object, mockTransactionTypeVmBuilder.Object);
Лично я стараюсь, чтобы мои классы зависели от интерфейсов, а не от конкретных классов, поэтому я могу высмеять свое сердце во время модульного тестирования и действительно ограничить объем каждого теста. – ESG
Короче говоря, наличие интерфейсов не решит проблему. Классы, у которых нет интерфейсов, имеют виртуальные методы - их все равно можно издеваться так же, как интерфейс.Поскольку для них никогда не будет альтернативной реализации, интерфейсы, которые просто позволяют насмехаться, не нужны. – JTech