【问题标题】:How to make Unit Tests aware of Application.Resources如何让单元测试了解 Application.Resources
【发布时间】:2012-02-25 15:08:02
【问题描述】:

我的 WPF 项目的 Application.Resources 区域中包含一个 ResourceDictionary。这个

来自 App.xaml(以 SO response 的方式):

App.xaml:

<Application.Resources>    
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>                
            <ResourceDictionary 
                  Source="MyDictionary.xaml">
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

在这本词典中,我有几种样式,包括页面样式:

MyDictionary.xaml:

<SolidColorBrush x:Key="PageBackgroundBrush" 
                     Color="Black" />

<Style x:Key="PageStyle" TargetType="Page">
        <Setter Property="Background" Value="{StaticResource ResourceKey=PageBackgroundBrush}" />
        <Setter Property="Height" Value="Auto" />
        <Setter Property="Width" Value="Auto" />
    </Style>

MyPage.xaml:

<Page x:Class="MyProject.MyPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="250"
      Title="Page"
      Style="{StaticResource ResourceKey=PageStyle}"
      >
<Grid>
</Grid>
</Page>

MyPage.xaml.cs

public class MyPage : Page
{
    public MyPage() 
    {
        // this part crashes during unit tests because 'PageStyle' was not found
        InitializeComponent();
    }
}

此设置在 Visual Studio 在设计模式下查看页面和运行项目时都非常有效。

我正在使用 Visual Studio's built in Unit Test tools 。当我尝试为 MyPage 类(在构造函数触发时使用 MyPage.xaml)进行单元测试时,我的测试失败了。 MyPage.xaml 使用 Application.Resources 中包含的字典中定义的样式。测试无法识别 PageStyle,因为在单元测试开始时未包含 Application.Resources,因此页面无法实例化。如何在单元测试中包含我的 Application.Resources?或者,是否有更好的方法来为 WPF 页面和窗口运行单元测试?

【问题讨论】:

  • 为什么标记会成为单元测试的一部分?
  • 我使用我当前的方法主要是因为这是我所知道的测试我为这个类(它继承自 Page)创建的构造函数的唯一方法。我愿意接受其他选择。
  • This question实际上为这个问题提供了解决方案。

标签: c# wpf visual-studio-2010 unit-testing xaml


【解决方案1】:

根据您的评论,我建议您使用Model-View-ViewModel (MVVM) 或任何其他方案从您的 GUI 级组件中提取尽可能多的逻辑,并在那里测试该逻辑。它并不能直接解决您当前的问题,但事实是 GUI 逻辑是出了名的难以测试 - 在我看来,使用 MS Test 和其他单元测试运行程序很难做到不值得。

对 GUI 进行单元测试是一个痛苦的世界(我已经尝试过)。通常有更好的工具来解决这个问题。

【讨论】:

  • 好吧,看起来答案是“不要在代码隐藏中放入太多代码,以至于单元测试是必要的”。我会将多余的代码从 xaml.cs 文件中移出并单独测试这些部分,从而更接近 MVVM 标准。
【解决方案2】:

我已经编写了一些有效的代码,并实际加载了我所缺少的真实项目,尽管https://stackoverflow.com/a/748440/57883 方法可能更适合隔离测试错误和构建测试库。

var targetAssembly = typeof(PracticeManagement.MainWindow).Assembly;
var currentAssembly = this.GetType().Assembly;

Application.ResourceAssembly = targetAssembly;

var rd = (ResourceDictionary)Application.LoadComponent(new Uri("/ProjectName;component/CommonUIStylesDictionary.xaml", UriKind.Relative));

if (Application.Current == null)
{
    var x = new System.Windows.Application(); // magically is assigned to application.current behind the scenes it seems
}

Application.Current.Resources = rd;

var mainWindow = new ProjectName.MainWindow(this.Connection.ConnectionString);

mainWindow.Show();

【讨论】:

  • 第二行的currentAssembly好像没用过
【解决方案3】:

似乎创建应用程序类的实例并调用 InitializeComponent 可以解决问题。

var app = new App(); //magically sets Application.Current
app.InitializeComponent(); //parses the app.xaml and loads the resources

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多