【问题标题】:Moq Application.Current.MainWindow in C#C# 中的最小起订量 Application.Current.MainWindow
【发布时间】:2017-10-26 21:04:15
【问题描述】:
我的视图模型中有如下代码。
private Generate()
{
// Some code here
var window = new CreateWindow
{
Owner = Application.Current.MainWindow
};
}
我想在我的单元测试中模拟 MainWindow 对象。我试过了
var app = new Application()
mock.SetupGet(x => x._mainWindow)
.Returns(It.IsAny<MainWindow>());
但 MainWindow 对象始终为空。
任何人都可以就这个问题提供一些有用的指示。
【问题讨论】:
标签:
c#
wpf
unit-testing
moq
viewmodel
【解决方案1】:
您可以创建一个 IMainWindowProvider 接口和 MainWindowProvider 实现:
public interface IMainWindowProvider
{
Window GetMainWindow();
}
public class MainWindowProvider : IMainWindowProvider
{
public Window GetMainWindow() => Application.Current.MainWindow;
}
然后在您当前的 Create 方法代码中,您可以使用此服务的实例(该实例可以在您要测试的容器类的构造函数中设置,并且在应用程序中它将是 MainWindowProvider 类的实例,例如依赖注入):
var window = new CreateWindow
{
Owner = mainWindowProvider.GetMainWindow()
};
在您的单元测试中,您可以模拟 IMainWindowProvider 而不是尝试模拟应用程序,并将模拟设置为返回一个虚拟的新窗口。
【解决方案2】:
您可能应该将 new CreateWindow 行包装成工厂模式。
创建一个新的 WindowFactory 类,它有一个方法和一个对应的接口 IWindowFactory。
然后在你的Generate 方法中调用注入的WindowFactory.Create() 方法。
在你的测试中注入一个模拟的 IWindowFactory,它返回一个假的 Window。
public interface IWindowFactory
{
CreateWindow Create();
}
public class WindowFactory : IWindowFactory
{
public CreateWindow Create()
{
return new CreateWindow { Owner = Application.Current.MainWindow };
}
}
在您的视图模型上添加一个属性
public IWindowFactory WindowFactory { get; set; }
在您的 Generate 方法中
var window = WindowFactory.Create();
然后在您的测试中,当您创建视图模型时,将 WindowFactory 设置为 Mock