2017-10-23 4 views
2

Android 기기 테스트에서 새로 생겼으며 기존 프로젝트에 유닛 테스트를 추가하고 싶습니다. MVP 디자인 아키텍처를 사용하고 있습니다. 내 발표자 내에서 기본값을 얻으려면 PreferenceManager을 호출하지만 항상 null을 반환합니다. 난 모방하는 방법에 대한 stackoverflow에 걸쳐 자습서 및 조언을 따랐습니다 PreferenceManagerSharedPreferences하지만 작동하지 않을 수 있습니다. 이것은 나의 발표자 클래스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 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); 
     } 
    } 
 

이 당신에 솔기를 줄 것이다 :

 

    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); 
     } 

    } 
 

그런 다음 발표자가이 같은 될 것 순수 단위 테스트 수행 :

 

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

조롱에 대해 걱정할 필요가 없습니다. PreferenceManager.

+0

당신의 솔루션은 기능적이지만 슬픈 사실은 커다란 프로젝트이기 때문에 나는 현재의 코드를 바꿀 수 없다는 것이다. 결정. 고맙습니다. 그래도. –

관련 문제