打包url和unit testing。 我的环境有问题吗?

所以我有一个很好的小MVVM解决方案,而且工作得很好。 我有一个标题栏的视图模型,根据应用程序的状态调整图标等。我已经完成验收测试,视图模型工作得很好。

所以我想对这个视图模型的行为进行unit testing 。 我创建了我的unit testing项目,为视图模型添加了一个新的unit testing,并编写了一个简单的冒烟测试。 (即给定模拟依赖项,类将实例化)。

巴姆,不

但是,正常运行时该类工作正常。 经过进一步检查,我的错误如下:

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 / /Media/Images/User_Normal.png / /Media/Images/User_Normal.png是图像路径/名称,此包URL在实践中有效。)

我的User_Normal.png包含的URL是否存在,文件是否存在,资源是否已正确打包到程序集中(使用reflection器检查)。

问题来自System.Uri类无法解释包URL。 这是我迷路的地方 。 为什么这不适用于测试范围。 我在我的测试项目中引用了所有WPF程序集:

  • WindowsBase
  • PresentationCore
  • PresentationFramework
  • System.Xaml

我错过了什么?

更新

好吧原来的问题是UriHandler没有注册包url。 (感谢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请求)
 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()

它看起来像打包url试图解决基于网络的assembly包url? 看起来处理程序的路由请求错误? 或者我错过了什么?

我曾经被这个问题咬过……

引用程序集是不够的。 WPF需要使用自己的URI解析器调用System.UriParser.Register() ,以便System.Uri可以解释包URL。

reflection告诉我们这是由System.IO.Packaging.PackUriHelper的静态构造函数完成的。 在测试中调用此类的任何方法,如PackUriHelper.Create()以确保URI解析器已正确注册。 有点丑,但应该工作。

在其他答案的基础上,这是使我的测试变为绿色的(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是我的主要应用程序类。 据推测,相关集会中的任何一类都会这样做。

一个小代码示例,可添加到上面的答案中。 我们在unit testing中使用以下内容来解决此问题。

  [AssemblyInitialize] public static void MagicHappensHere(TestContext context) { PackUriHelper.Create(new Uri("reliable://0")); } 

一旦在测试启动时调用它,它们都可以完美地工作。

我认为您可以通过在运行任何测试之前创建主应用程序类的实例来解决此问题。 这将连接Julien在另一个答案中提及的处理程序。