所以我有一个很好的小MVVM解决方案,而且工作得很好。我有一个标题栏的视图模型,可以根据应用程序的状态调整图标等。我已经完成了验收测试,视图模型效果很好。
所以我想单元测试这个视图模型的行为。我创建了我的单元测试项目,为视图模型添加了一个新的单元测试,并编写了一个简单的冒烟测试。 (即,给定模拟的依赖项,类将实例化)。
Bam,没有
但是,正常运行时该类工作正常。经过进一步检查,我的错误如下:
TestInitialize threw exception: System.UriFormatException: Invalid URI: Invalid port specified.
因此,在调用堆栈之后,我得出的结论是,用于加载资源流的包URL是踢错误的。
pack://application:,,,/Operations.Shell;component/Media/Images/User_Normal.png
(注意:Operations.Shell
是程序集名称,/Media/Images/User_Normal.png
是图像路径/名称,此包URL 在实践中。)
我的User_Normal.png包含的URL是否存在,文件是否存在,资源是否已正确打包到程序集中(使用反射器检查)。
问题来自System.Uri
类无法解释包网址。 这是我迷路的地方。为什么这不适用于测试范围。我在测试项目中引用了所有WPF程序集:
我错过了什么?
更新
好吧原来的问题是UriHandler没有注册包网址。 (感谢Julien Lebosquain)现在已经修复了它仍然存在问题。
TestInitialize threw exception: System.NotSupportedException: The URI prefix is not recognized.
System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase) System.Net.WebRequest.Create(Uri requestUri) MS.Internal.WpfWebRequestHelper.CreateRequest(Uri uri) System.IO.Packaging.PackWebRequest.GetRequest(Boolean allowPseudoRequest) System.IO.Packaging.PackWebRequest.GetResponse() MS.Internal.WpfWebRequestHelper.GetResponse(WebRequest request) System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle) System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache) System.Windows.Media.Imaging.BitmapImage.FinalizeCreation() System.Windows.Media.Imaging.BitmapImage.EndInit() System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource, RequestCachePolicy uriCachePolicy) System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource) MyFramework.Resources.b__1(Uri u) MyFramework.Resources.ResourceType`1.Load(String path) Operations.Shell.AppShell.ViewModels.HeaderViewModel..ctor(IEventAggregator eventAggregator, ISecurityService securityService) Tests.Shell.AppShell.TestHeaderViewModel.TestInitialize()
看起来这个包网址试图解决基于网络的装配包网址?看起来处理程序的路由请求错误?或者我错过了什么?
答案 0 :(得分:18)
我也曾被这个问题咬过......
引用程序集是不够的。 WPF需要使用自己的URI解析器调用System.UriParser.Register()
,以便System.Uri
可以解释包URL。
反映告诉我们这是由System.IO.Packaging.PackUriHelper
的静态构造函数完成的。在测试中调用此类的任何方法,如PackUriHelper.Create()
,以确保URI解析器已正确注册。有点丑,但应该有效。
答案 1 :(得分:13)
在其他答案的基础上,这是使我的测试变为绿色的(NUnit)代码:
在AssemblyInfo.cs中:
[assembly: RequiresSTA]
在自己的档案中:
[SetUpFixture]
public class PreTestSetup
{
[SetUp]
public void Setup()
{
PackUriHelper.Create(new Uri("reliable://0"));
new FrameworkElement();
System.Windows.Application.ResourceAssembly = typeof (App).Assembly;
}
}
App是我的主要应用程序类。据推测,相关集会中的任何一类都会这样做。
答案 2 :(得分:3)
要添加到上述答案的小代码示例。我们在单元测试中使用以下内容来解决此问题。
[AssemblyInitialize]
public static void MagicHappensHere(TestContext context) {
PackUriHelper.Create(new Uri("reliable://0"));
}
一旦在测试启动时调用了它,它就完美无缺。
答案 3 :(得分:1)
我认为您可以通过在运行任何测试之前创建主应用程序类的实例来解决此问题。这将连接Julien在另一个答案中提到的处理程序。