C# 中的最小起订量 Application.Current.MainWindow

Moq Application.Current.MainWindow in C#

我的视图模型中有如下代码。

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 对象始终为空。

任何人都可以就此问题提供一些有用的指示。

您可能应该将 new CreateWindow 行包装到工厂模式。

创建一个新的WindowFactory class,它只有一个方法和一个对应的接口IWindowFactory.

然后在您的 Generate 方法中调用注入的 WindowFactory.Create() 方法。

在你的测试中注入一个模拟的 IWindowFactory 其中 returns 一个假的 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; }

在您的生成方法中

var window = WindowFactory.Create();

然后在您的测试中,当您创建视图模型时,将 WindowFactory 设置为 Mock

您可以创建一个 IMainWindowProvider 接口和 MainWindowProvider 实现:

public interface IMainWindowProvider
{
    Window GetMainWindow();
}

public class MainWindowProvider : IMainWindowProvider
{
    public Window GetMainWindow() => Application.Current.MainWindow;
}

然后在您当前的 Create 方法代码中,您可以使用此服务的实例(该实例可以在您要测试的容器 class 的构造函数中设置,并且在应用程序中它将是 MainWindowProvider class 的一个实例,例如依赖注入:

var window = new CreateWindow
{
    Owner = mainWindowProvider.GetMainWindow()
};

并且在您的单元测试中,您可以模拟 IMainWindowProvider 而不是尝试模拟应用程序,并将模拟设置为 return 一个虚拟的新 Window。