5

我正在尝试设置一个 MvvmCross 应用程序项目并针对它运行单元测试(即其中的视图模型)。我在 OS X(v. 4.0.4,撰写本文时最新)上使用 Xamarin Studio。

MvvmCross App 设置为可移植类库。测试程序集设置为引用 NUnit 框架的普通 Mono/.Net 程序集(不是 PCL)。

尝试执行测试时,它们以System.TypeLoadException.

我已经在Mono 绑定登录的情况下运行了测试。这是输出:

单声道:无法加载从 /Users/jr/dev/rowinginmotion-cross/RowingInMotion.Mobile.BoatApp.Tests/bin/Debug/Cirrious.MvvmCross.dll 引用的以下程序集:程序集:系统(assemblyref_index=3)版本: 2.0.5.0 公钥:7cec85d7bea7798e 系统错误:参数无效

单声道:无法加载程序集 Cirrious.MvvmCross [0x559960]

Mono:无法加载文件或程序集“系统,版本=2.0.5.0,文化=中性,PublicKeyToken=7cec85d7bea7798e,可重定位=是”或其依赖项之一。

不支持此测试设置吗=

4

2 回答 2

5

此问题与 Xamarin 和 Mono 尚未正确支持可移植类库这一事实有关 - 相反,它们根据您已加载的 Mono 版本(Xamarin.Android、Xamarin.iOS 等)编译和链接本地固定程序集-有关更多信息,请参阅http://slodge.blogspot.co.uk/2013/01/almost-portable-binaries.html 。

在 Windows 上,您可以使用BindingRedirect功能解决这个问题,但我还没有找到任何方法来解决在 Xamarin 环境中使用 XBuild 的问题(例如,请参阅http://forums.xamarin上的我的 PCL 和 Mac 问题.com/discussion/3733/playing-with-pcls

我能看到当前在完整的 .Mac (.Net) 项目中加载此代码的唯一方法是使用 Xamarin 推荐的文件链接方法 - 复制项目文件并专门针对适当的目标编译副本。

希望这会很快改变——因为官方 PCL 支持将在未来几天和几周内以 alpha 形式发布。

于 2013-05-08T13:48:47.023 回答
1

除了@Stuart 的答案(这是正确的),我想发布第二个解决方法,我发现它可以让我实现我想要的场景(PCL 程序集可在 Mac OS 和 Windows 上测试)。

此解决方法依赖于引入对通配符包含的支持的 Xamarin Studio 4.0.5(或更高版本)。

具体来说,在 Windows 上编译时,我编译 PCL 并从测试程序集中添加一个项目引用。在 Mac OS 上,我也编译了“PCL”(目前还没有真正的 PCL 支持),但我在测试程序集中保持不变。相反,我将通配符包含来自 PCL 项目的所有代码到测试程序集中,因此我在 OS X 上的测试程序集中有测试+代码。

这需要一些 MSBuild 魔法(用于在 Windows 和 OS X 版本之间切换 MvvmCross 引用的类似技巧)。在项目顶部包含此 .targets 文件:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
    <MvvmCrossPlatform>VS2012</MvvmCrossPlatform>
    <PclSupport>true</PclSupport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
    <MvvmCrossPlatform>XS-iOS-Mac</MvvmCrossPlatform>
    <PclSupport>false</PclSupport>
  </PropertyGroup>
</Project>

然后在您的单元测试 .csproj 中:

  <ItemGroup Condition=" '$(PclSupport)' == 'false' ">
    <Compile Include="..\RowingInMotion.Mobile.Backend\**\**.cs">    
      <Link>_Inlined\%(RecursiveDir)%(FileName)%(Extension)</Link>  
    </Compile>
  </ItemGroup>

  <Choose>
    <When Condition=" '$(PclSupport)' == 'true' ">
      <ItemGroup>
        <ProjectReference Include="..\RowingInMotion.Mobile.Backend\RowingInMotion.Mobile.Backend.csproj">
          <Project>{0B448743-182C-4ADC-8E97-7F9E7EF3A03A}</Project>
          <Name>RowingInMotion.Mobile.Backend</Name>
        </ProjectReference>
      </ItemGroup>
    </When>
  </Choose>

请注意,我必须使用 Choose 构造来使 ProjectReference 有条件,似乎只是在其项目组上使用 Condition 不会使 Visual Studio 和 Xamarin Studio 加载/忽略项目引用。Xamarin Studio 似乎也没有正确扩展%(RecursiveDir)...语句,因此文件保留了它们丑陋的文件名(只要它们隐藏在它们的 _Inlined 文件夹中,我就不会在意)。

于 2013-05-14T07:31:43.403 回答