NUnit并测试Xamarin PCL

Phi*_*ray 4 c# mono unit-testing xamarin.ios xamarin

我正在开发一种便携式类库和iOS的应用,其中数据访问是基于顶部保罗贝茨 ModernHttpClient,齐射,改装Akavache库.这适用于PCL和iOS应用程序,但在针对PCL创建单元测试时遇到问题.

如果我使用在Visual Studio 2015中运行的Resharper测试,我的所有测试都会通过,但如果我在Xamarin Studio中运行NUnit测试,大约一半的测试会因TypeLoadExceptions而失败.我试图确定哪个dll导致我的问题,但据我所知,一切都是应有的.

正在测试的PCL类

   internal class ApiService<TRefitService> : IApiService<TRefitService> where TRefitService : IServiceContract
    {
        private readonly Lazy<TRefitService> background;
        private readonly Lazy<TRefitService> userInitiated;
        private readonly Lazy<TRefitService> speculative;

        private ApiService(){}

        public ApiService(string baseUrl)
        {
            ParameterGuard.ThrowIfNullOrEmpty(baseUrl, nameof(baseUrl));

            Func<string, RateLimitedHttpMessageHandler, TRefitService> createClient = (address, handler) =>
            {
                HttpClient client = new HttpClient(handler) {BaseAddress = new Uri(address)};
                return RestService.For<TRefitService>(client);
            };

            background = new Lazy<TRefitService>(() => createClient(baseUrl, new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.Background)));
            speculative = new Lazy<TRefitService>(() => createClient(baseUrl, new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.Speculative)));
            userInitiated = new Lazy<TRefitService>(() => createClient(baseUrl, new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.UserInitiated)));
        }

        /// <summary>
        /// Use for network requests that are running in the background.
        /// </summary>
        public TRefitService Background => background.Value; 

        /// <summary>
        /// Use to fetch data into a cache when a page loads. Expect that these requests will only get so far then give up and start failing.
        /// </summary>
        public TRefitService Speculative => speculative.Value;

        /// <summary>
        /// Use for network requests that are fetching data that the user is waiting on *right now*.
        /// </summary>
        public TRefitService UserInitiated => userInitiated.Value;
    }
Run Code Online (Sandbox Code Playgroud)

Xamarin Studio失败测试

        [Test()]
        public void PassingInANullBaseUrlThrowsAnException()
        {
            Assert.Throws<ArgumentNullException>(() => new ApiService<IAuthorisationApi>(null));
        }
Run Code Online (Sandbox Code Playgroud)

测试结果

预期:但是:(无法在NUnit.Framework中从程序集'/Users/206474978/Desktop/test/test/test/bin/Debug/xxx.xxx.xxx.dll'中加载类型'ApiService`1'.). Assert.Throws(IResolveConstraint表达式,NUnit.Framework.TestDelegate代码,System.String消息,System.Object [] args)<0x377c1c8 + 0x000e6> in:0

在NUnit.Framework.Assert.That(System.Object actual,IResolveConstraint expression,System.String message,System.Object [] args)<0x377c888 + 0x000bf> in:0 at NUnit.Framework.Assert.Throws(IResolveConstraint expression,NUnit) .Framework.TestDelegate代码,System.String消息,System.Object [] args)<0x377c1c8 + 0x00137> in:0
at NUnit.Framework.Assert.Throws(System.Type expectedExceptionType,NUnit.Framework.TestDelegate code,System.String消息,System.Object [] args)<0x377bfc8 + 0x0004f> in:0
at NUnit.Framework.Assert.Throws [T](NUnit.Framework.TestDelegate code,System.String message,System.Object [] args)<0x377bf58 + 0x00033> in:0 at NUnit.Framework.Assert.Throws [T](NUnit.Framework.TestDelegate code)<0x377bf08 + 0x0003b> in:0 at test.Test + ApiServiceTest.PassingInANullBaseUrlThrowsAnException()[0x00001] in/Users/206474978/Desktop/test/test/test/Test.cs:37 at(包装器托管到本机)System.Reflection.MonoMethod:InternalInvoke(System.Reflection.MonoMethod,object,o System.Reflection.MonoMethod.Invoke(System.Object obj,BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object [] parameters,System.Globalization.CultureInfo culture)[0x00038] in bject [],System.Exception&) /private/tmp/source-mono-4.2.3/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.3/mcs/class/corlib/System.Reflection /MonoMethod.cs:295

现在这通常不会成为问题,因为我只使用重塑器,但我正在Jenkins之上构建我们的持续集成管道,并通过Xamarin库中的nunit包运行测试,这导致构建报告失败.

知道这里的问题是什么吗?

UPDATE

好的,按照SushiHangover的提示,我使用了最新版本的NUnit测试运行器并得到了以下输出.似乎错误是TypeLoadException或BadImageFormatException但我不确定为什么.我检查了两个项目的输出,两者都设置为AnyCPU.

    [Test()]
public void PassingInAValidBaseAddressGivesAValidRefitUserInitiatedObject()
{
    var api = new ApiService<IAuthorisationApi>(BaseAddress);
    Assert.IsNotNull(api.UserInitiated);
}

    [Test()]
    public async Task PassingInAValidBaseAddressReturnsAValidAccountFromTheBackgroundObject()
    {
        //Arrange
        ApiService<IAuthorisationApi> service = = new ApiService<IAuthorisationApi>(BaseAddress);;
        //Act

        AuthorisationDto account = await service.Background.GetAuthorisationToken(logonPost, "ireland");
        //Assert
        Assert.IsTrue(account != null);
    }
Run Code Online (Sandbox Code Playgroud)

无效类型xxx.xxx.Core.Services.Lib.ApiService`1,例如字段xxx.xxx.Core.Tests.ApiServiceTest + c__async0:__ 0

7) Error : xxx.xxx.Core.Tests.ApiServiceTest.PassingInAValidBaseAddressGivesAValidRefitUserInitiatedObject
System.TypeLoadException : Failure has occurred while loading a type.
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x3083b38 + 0x00093> in <filename unknown>:0 

8) Error : xxx.xxx.Core.Tests.ApiServiceTest.PassingInAValidBaseAddressReturnsAValidAccountFromTheBackgroundObject
System.BadImageFormatException : Could not resolve field token 0x040001ae
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x3083b38 + 0x00093> in <filename unknown>:0 
Run Code Online (Sandbox Code Playgroud)

更新2

另一个测试失败了下面的堆栈跟踪,这看起来像单声道的一些问题?

System.TypeLoadException:无法从程序集'/Users/206474978/Documents/Development/Projects/BRSMemberApp/UnitTests/BrsGolf.Members.Core.Tests/bin/Debug/Brs.Members.Core.dll加载'ApiService`1'类型".

at(包装器托管到本机)System.Reflection.MonoMethod:System.Reflection.MonoMethod.Invoke中的InternalInvoke(System.Reflection.MonoMethod,object,object [],System.Exception&)(System.Object obj,BindingFlags invokeAttr, System.Reflection.Binder binder,System.Object [] parameters,System.Globalization.CultureInfo culture)[0x00038] in /private/tmp/source-mono-4.2.3/bockbuild-mono-4.2.0-branch/profiles/单MAC-xamarin /建立根/单4.2.3/MCS /类/ corlib /的System.Reflection/MonoMethod.cs:295

Sus*_*ver 5

(这与我发布的旧答案有关)

安装的Mono框架包含相对较旧的版本NUnit(版本2.4.8).该版本中存在许多问题/错误,范围从错误的异常捕获到解决方案/项目解析问题.

我们为OS-X构建(包括Jenkins CI)所做的是通过nuget将最新的NUnit安装到我们的解决方案根目录,并使用该安装进行构建工件的本地测试.

就像是:

cd YourSolutionRootDir
nuget install nunit.runners
mono ./NUnit.ConsoleRunner.3.2.0/tools/nunit3-console.exe MyTestProject/bin/debug/except.dll
Run Code Online (Sandbox Code Playgroud)