我正在尝试建立一个MvvmCross应用程序项目并对其运行单元测试(即其中的视图模型)。我在OS X上使用Xamarin Studio (v. 4.0.4,撰写本文时最新)。
MvvmCross App被设置为一个可移植的类库。测试组件设置为普通的单声道/。Net程序集(不是PCL)引用NUnit框架。
当尝试执行测试时,它们以System.TypeLoadException
失败。
我已经使用Mono绑定登录运行了测试。下面是输出:
Mono:下面的程序集从/用户/小/dev/rowinginmotion-cross/RowingInMotion.Mobile.BoatApp.Tests/bin/调试/Cirrious.MvvmCross.dll无法加载:汇编:System (assemblyref_index=3)版本:版2.0.5.0公钥:7cec85d7bea7798e系统错误:无效参数
Mono:未能加载程序集Cirrious。MvvmCross [0 x559960]
Mono:无法加载文件或程序集'System, Version=2.0.5.0,Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or它的一个依赖项。
是否不支持此测试设置=
这个问题与Xamarin和Mono还没有正确支持可移植类库的事实有关-相反,它们根据Mono (Xamarin)的哪个版本编译和链接本地固定的程序集。Android, Xamarin的。iOS等)加载-参见http://slodge.blogspot.co.uk/2013/01/almost-portable-binaries.html获取更多信息。
在Windows上,你可以使用BindingRedirect
功能来解决这个问题,但我还没有找到任何方法来解决Xamarin环境中使用XBuild的问题(例如,参见我的PCL和Mac问题http://forums.xamarin.com/discussion/3733/playing-with-pcls)
目前我能看到的在一个完整的。mac (. net)项目中加载这段代码的唯一方法是使用Xamarin推荐的文件链接方法——复制项目文件并针对适当的目标编译副本。
希望这种情况很快就会改变-因为官方的PCL支持将在未来几天或几周内发布alpha版本。
除了@Stuart的答案(这是正确的),我想发布第二个解决方案,我发现它可以让我实现我想要的场景(PCL组装测试在Mac OS和Windows上)。
这个解决方法依赖于Xamarin Studio 4.0.5(或更高版本),它引入了对通配符包含的支持。
具体来说,当在Windows上编译时,我编译PCL并从测试汇编中添加一个项目引用。在Mac OS上,我也编译了"PCL"(现在还没有真正的PCL支持),但我把它从测试汇编中保留下来。相反,我通配符包括来自PCL项目的所有代码到测试程序集中,所以我在OS x上的测试程序集中有test+代码。
这需要一些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.BackendRowingInMotion.Mobile.Backend.csproj">
<Project>{0B448743-182C-4ADC-8E97-7F9E7EF3A03A}</Project>
<Name>RowingInMotion.Mobile.Backend</Name>
</ProjectReference>
</ItemGroup>
</When>
</Choose>
请注意,我必须使用Choose构造来使ProjectReference有条件,似乎只是在其项目组上使用条件并不能使Visual Studio和Xamarin Studio加载/忽略项目引用。似乎Xamarin Studio没有适当地扩展%(RecursiveDir)...
语句,所以文件保留他们丑陋的文件名(不是我关心,只要他们隐藏在他们的_inline文件夹)。