2017-10-23 12 views
2

私はAndroidのユニットテストで新しく、私はいくつかのユニットテストを既存のプロジェクトに追加したいと思います。私はMVP設計アーキテクチャを使用しています。私の発表者の中では、デフォルトのSharedPrefencesを得るためにPreferenceManagerを呼び出していますが、常にnullを返します。私はPreferenceManagerSharedPreferencesを模擬する方法についていくつかのチュートリアルとアドバイスをstackoverflowに従ってきましたが、動作させることはできません。これは私のプレゼンタークラスMockitoのMock PreferenceManager

@RunWith(MockitoJUnitRunner.class) 
public class SettingsPresenterTest { 
    @Mock 
    private SettingsView mView; 
    @Mock 
    private LocalConfiguration conf; 
    private SettingsPresenter mPresenter; 

    public SettingsPresenterTest() { 
     super(); 
    } 

    @Before 
    public void startUp() throws Exception { 
     MockitoAnnotations.initMocks(LocalConfiguration.class); 
     MockitoAnnotations.initMocks(PreferenceManager.class); 


     mPresenter = new SettingsPresenter(mView); 


     final SharedPreferences sharedPrefs = 
     Mockito.mock(SharedPreferences.class); 
     final Context context = Mockito.mock(Context.class); 

     Mockito.when(PreferenceManager.getDefaultSharedPreferences(context)). 
     thenReturn(sharedPrefs); 
    } 


    @Test 
    public void notificationsEnabledClicked() throws Exception { 
     boolean notifsEnabled = false; 
     mPresenter.notificationsEnabledClicked(notifsEnabled); 

     Mockito.verify(mView).setNotificationsView(notifsEnabled); 
    } 
} 

であり、ここでSharedPreferences

public class LocalConfiguration { 
    public TerritoryDto getLastSavedTerritory() { 
      SharedPreferences preferences = 
      PreferenceManager.getDefaultSharedPreferences(H.getContext()); 
      String terrritoryString = preferences.getString(SAVED_TERRITORY, 
      null); 
      return 
      SerializerHelper.getInstance().deserialize(terrritoryString, 
      TerritoryDto.class); 
    } 
} 

はあなたが私にこのエラーを解決する方法についていくつかのガイドラインを与えることができるnullを返される方法はありますか?

答えて

2

Android SDKを直接参照するのではなく、プレゼンターのロジックから抜粋してください。つまり、PreferenceManager.getDefaultSharedPreferences()を実行する代わりに、抽象化を作成して、抽象化からterritoryStringを求めてください。

これはあなたの発表者が、Android SDKのPreferenceManagerでもSharedPreferencesでもないことをプレゼンターが知りませんので、純粋なユニットテストを実行するのに十分な継ぎ目があります。

これを言えば、抽象化を実装しましょう。宣言した次のインタフェースた:具体的な実装これに

 

    public interface Storage { 
     @Nullable 
     String getSavedTerritory(); 
    } 
 

は次のようになります。

 

    public SharedPrefsStorage implements Storage { 

     private final SharedPreferences prefs; 

     public SharedPrefsStorage(Context context) { 
      prefs = PreferenceManager.getDefaultSharedPreferences(); 
     } 

     @Nullable 
     @Override 
     public String getSavedTerritory() { 
      return prefs.getString(SAVED_TERRITORY, null); 
     } 

    } 
 

次に、あなたのプレゼンターはこのようなものになる:これはにあなたの継ぎ目を与えるだろう

 

    public class LocalConfiguration { 

     final Storage storage; 

     public LocalConfiguration(Storage storage) { 
      this.storage = storage; 
     } 

     public TerritoryDto getLastSavedTerritory() { 
       final String territory = storage.getSavedTerritory(); 

       return SerializerHelper.getInstance().deserialize(territory, TerritoryDto.class); 
     } 
    } 
 

純粋なユニットテストを実行してください:

 

    @Test 
    void someTest() { 
     when(storage.getSavedTerritory()).thenReturn("New York"); 
     ... 
    } 
 

PreferenceManagerをもう一度嘲笑することを心配する必要はありません。

+0

あなたのソリューションは機能的ですが、悲しい事実は、大きなプロジェクトで、私はここ1ヶ月間ここにいたので、私はそのようなコードを取ることができないので、少なくとも現時点ではコードを変更できないということです決定。ありがとうございました。しかし、。 –