2010-09-14 69 views
14

所以我有这个不错的小MVVM解决方案,而且事情很好。我有一个用于根据应用程序状态调整图标的标题栏视图模型等。我已经完成了验收测试,视图模型效果很好。包装网址和单元测试。我的环境问题?

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

Bam,no

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

TestInitialize threw exception: System.UriFormatException: Invalid URI: Invalid port specified.

所以下面的调用堆栈我在我的包网址,用来加载资源流是那些踢的错误结论。

pack://application:,,,/Operations.Shell;component/Media/Images/User_Normal.png

(注:Operations.Shell是集名称,/Media/Images/User_Normal.png是图像路径/名称,而这个包网址在实践工作

是包网址我有我的User_Normal.png,文件存在,资源被正确打包到程序集中(使用反射器进行检查)。

问题出在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 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() 

它看起来像包URL的尝试基于Web的程序集包的URL地址来点什么?看起来像处理程序的路由请求错误?或者我错过了什么?

+0

@Downvoter,你有没有理由? – Aren 2011-01-05 17:12:03

回答

16

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

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

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

+0

@Julien Lebosquain - 你是对的(+1),但仍然存在问题。请参阅原始文章中的更新部分以获取更多详细信息。你也有这个问题吗? – Aren 2010-09-14 17:03:30

+2

解决了它。 WPF框架还有更多的需要初始化来为WebRequest/WebResponse添加一个url-prefix处理程序。我最终实例化了一个'FrameworkElement'对象,它似乎通过静态构造函数加载了足够的框架。 – Aren 2010-09-14 19:29:11

+2

创建FrameworkElement将启动与创建应用程序类相同的过程,但它可能会更快。很高兴知道! – 2010-09-14 21:18:34

1

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

+0

我宁愿不旋转我的应用程序来测试组件。 – Aren 2010-09-14 16:55:41

2

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

[AssemblyInitialize] 
    public static void MagicHappensHere(TestContext context) { 

     PackUriHelper.Create(new Uri("reliable://0")); 
    } 

一旦这个被称为在测试启动这一切完美的作品。

12

建立在其他的答案,这里,使我的测试去绿色(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是我的主要应用程序类。据推测,相关大会中的任何班级都会这样做。

+0

对我来说,在我的测试中也有诀窍;谢谢! – 2011-07-21 05:59:03