2017-09-04 33 views
0

我在Visual Studio for Mac中設置了一個TestProject,它引用了我的Xamarin Forms項目,用於測試我的代碼的非可視部分。Xamarin單元測試Xamarin.Auth的便攜式誘餌和開關錯誤?

但是,當我嘗試測試一段利用Xamarin.Auth訪問鑰匙串的代碼時,出現以下錯誤。

System.NotImplementedException : 
Portable Bait And Switch is nuget feature, so the package must be installed in all project. 

NotImplementedException will indicate that Portable Code from PCL is used and not Platform Specific 
implementation. Please check whether platform specific Assembly is properly installed. 

Cannot save account in Portable profile - bait-and-switch error. 
Please file a bug in https://bugzilla.xamarin.com 

此代碼工作在iOS模擬器罰款運行,我認爲它是與xamarin身份驗證的方式充分利用了IOS鑰匙串中不存在在這個測試項目。我試圖在引用中添加我的ios解決方案,但我無法在我的測試項目的「編輯引用」中這樣做。項目引用對話框不會允許它:enter image description here

這是我的PCL失敗的代碼。

AccountStore store; 
store = AccountStore.Create(); 

顯然,這與AccountStore.Create()麻煩

這裏是testcode類調用PCL:

using System; 
using NUnit.Framework; 
using CrowdWisdom; 
using CrowdWisdom.Authentication; 

namespace CrowdWisdomTest 
{ 
    [TestFixture()] 
    public class AuthServiceTest 
    { 
     [Test()] 
     public void SaveRestoreSecret() 
     { 
      String secret = "ABCD"; 
      AuthService auth = AuthService.GetInstance(); 
      auth.putSecret("MySecret", secret); 
      Assert.AreEqual(secret, auth.GetSecret("MySecret")); 
    } 
    } 
} 
+2

Xamarin.Auth使用平臺特定的API,所以你要麼需要使用特定於平臺的設備亞軍(NUnit的和的xUnit有iOS和Android基於亞軍),或者嘲笑你的授權過程,所以你可以在沒有基於非平臺的NUnit亞軍的情況下進行測試。 – SushiHangover

回答

1

偷樑換柱,大多數跨平臺的插件使用模式 - 不是一個非常適合單元測試的模式。正如你在你的例子中看到的那樣。

我的第一個建議是使用基於合同的方法,以及爲您的授權過程使用依賴注入容器;所以你可以提供一個模擬實現作爲單元測試的上下文。但是,如果這是不可能的,那麼你可以使用下面的hack來爲這些靜態類提供你自己的模擬開關。

基本上,您看到的錯誤是因爲您的便攜式代碼正在訪問僅用於誘餌的便攜式版本Xamarin.Auth。所以你將不得不創建自己的實現來充當單元測試環境中的切換(就像他們在Xamarin.Auth中的特定於平臺的庫中所做的那樣)。

爲了做到這一點,你將需要:

  1. 創建另一個便攜式庫(將僅由您的單元測試項目中使用)。假設我們將其命名爲Xamarin.Auth.Mocks。確保在其屬性頁面中將根名稱空間和程序集名稱更新爲'Xamarin.Auth'。

    enter image description here

  2. 添加一個模擬帳戶存儲類和使用開關模式實現AccountStore。在每次運行單元測試時您的單元測試庫

現在,您的便攜式代碼

namespace Xamarin.Auth 
{ 
    /// <summary> 
    /// A persistent storage for <see cref="Account"/>s. This storage is encrypted. 
    /// Accounts are stored using a service ID and the username of the account 
    /// as a primary key. 
    /// </summary> 
#if XAMARIN_AUTH_INTERNAL 
    internal abstract partial class AccountStore 
#else 
    public abstract partial class AccountStore 
#endif 
    { 
     public static AccountStore Create() 
     { 
      return new MockAccountStore(); 
     } 
    } 

    public class MockAccountStore : AccountStore 
    { 

    } 
} 
  • 添加參考Xamarin.Auth.Mocks,會發現所有的Xamarin.Auth需要你的模擬開關實現,並且你從Xamarin.Auth實現真正的隔離;這在技術上是我們在編寫單元測試時渴望的東西。

    注:如果您的便攜式的代碼使用其他誘餌開關類,也增加模擬實現了他們在你Xamarin.Auth.Mocks庫。你只需要爲代碼中使用的類添加模擬類;不是所有的類中Xamarin.Auth

  • +1

    哇,很好的回答!謝謝 – user1023110