2017-12-12 10 views
1

로컬 데이터 소스을 모의 할 필요가있는 내 Presenter에 대한 단위 테스트를 작성합니다.Error mocking SQLiteOpenHelper에 대한 참조를 보유하는 클래스

여기 내 간단한 테스트입니다 : 내가 뭔가 이상한 발견

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.dai.uangteman.data.AddressLocalDataSource. 

Mockito can only mock non-private & non-final classes. 
If you're not sure why you're getting this error, please report to the mailing list. 

Java    : 1.8 
JVM vendor name : Oracle Corporation 
JVM vendor version : 25.77-b03 
JVM name   : Java HotSpot(TM) 64-Bit Server VM 
JVM version  : 1.8.0_77-b03 
JVM info   : mixed mode 
OS name   : Mac OS X 
OS version   : 10.12.6 

Underlying exception : java.lang.IllegalArgumentException: Could not create type 

    at com.dai.uangteman.view.fragment.presenter.AddressPresenterTest.beforeTest(AddressPresenterTest.java:41) 
... 
Caused by: java.lang.IllegalArgumentException: Could not create type 
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:140) 
    ... 28 more 
Caused by: java.lang.NoClassDefFoundError: android/database/sqlite/SQLiteOpenHelper 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:138) 
    ... 45 more 
Caused by: java.lang.ClassNotFoundException: android.database.sqlite.SQLiteOpenHelper 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
    ... 87 more 

난 내 AddressLocalDataSource 클래스를 변경하는 해결

public class AddressPresenterTest { 
    @Mock 
    private AddressView mView; 

    @Mock 
    private AddressDataSource mDataSource; 

    @Mock 
    private AddressLocalDataSource mLocalDataSource; 

    @Captor 
    ArgumentCaptor<DataSourceCallback<Province>> mProvinceCallbackCaptor; 

    private AddressPresenter mPresenter; 

    @Before 
    public void beforeTest() { 
     MockitoAnnotations.initMocks(this); 

     mPresenter = new AddressPresenter(mDataSource, mView); 
     mPresenter.setLocalDataSource(mLocalDataSource); 
    } 

    @Test 
    public void When_SelectProvince_DataIsNull_ShowErrorMessage() { 
     mPresenter.getLocalProvinceById(2129023); 

     // Cause data source has callback, we need to capture the callback 
     ArgumentCaptor<Integer> provinceIdCaptor = ArgumentCaptor.forClass(Integer.class); 
     verify(mLocalDataSource).fetchProvinceById(provinceIdCaptor.capture(), mProvinceCallbackCaptor.capture()); 
     mProvinceCallbackCaptor.getValue().onFailedLoad(); 

     verify(mView).loadContentError(); 
    } 
} 

나는 오류를 가지고이 테스트를 실행

.

내가 뭘 찾았는지 아래
public class AddressLocalDataSource { 
    private StaticDatabaseHelper mDatabaseHelper; 

// /** 
//  * @param mDatabaseHelper 
//  */ 
// public AddressLocalDataSource(StaticDatabaseHelper mDatabaseHelper) { 
//  this.mDatabaseHelper = mDatabaseHelper; 
// } 

    public void setDatabaseHelper(StaticDatabaseHelper mDatabaseHelper) { 
     this.mDatabaseHelper = mDatabaseHelper; 
    } 
    ... 
} 

:

  1. 내가 StaticDatabaseHelper 개체 매개 변수를 포함 내 생성자와 setter 메소드를 제거하려고하고 작동!
  2. 나는 setter 메서드에서 StaticDatabaseHelper 초기화를 변경하려고 시도하지만 작동하지 않습니다!

문제는 내 AddressLocalDataSource 필요 인스턴스가 StaticDatabaseHelper 클래스입니다.

아이디어가 있으십니까? 고마워요

답변

0

✔ 대답

, 내가 가장 간단한 솔루션을 얻을. 테스트를 위해 안드로이드 라이브러리에 불완전한 부분이 있다고 생각합니다. 난 그냥이 경우 StaticDatabaseHelper 클래스를 조롱,

./gradlew clean test 

을 그리고 지금은 작동 : 그래서 난 그냥 정리에이 Gradle을 명령을 실행합니다. ,

public class AddressPresenterTest { 

    @Mock 
    private AddressView mView; 

    @Mock 
    private AddressDataSource mDataSource; 

    @Mock 
    private AddressLocalDataSource mLocalDataSource; 

    @Captor 
    ArgumentCaptor<DataSourceCallback<Province>> mProvinceCallbackCaptor; 

    private AddressPresenter mPresenter; 

    @Before 
    public void beforeTest() throws Exception { 
     MockitoAnnotations.initMocks(this); 

     mPresenter = new AddressPresenter(mDataSource, mView); 
     mPresenter.setLocalDataSource(mLocalDataSource); 
    } 

    @Test 
    public void When_SelectProvince_DataIsNull_ShowErrorMessage() { 
     mPresenter.getLocalProvinceById(2129023); 

     // Cause data source has callback, we need to capture the callback 
     ArgumentCaptor<Integer> provinceIdCaptor = ArgumentCaptor.forClass(Integer.class); 
     verify(mLocalDataSource).fetchProvinceById(provinceIdCaptor.capture(), mProvinceCallbackCaptor.capture()); 
     mProvinceCallbackCaptor.getValue().onFailedLoad(); 

     verify(mView).loadContentError(); 
    } 
} 

희망이 도움이 당신에게

감사합니다 : 그래서이 클래스 내 최종 테스트입니다
1

StaticDatabaseHelper도 모방해야합니다. 그런 다음 Mockito는 조롱 된 인스턴스를 AddressLocalDataSource에 자동으로 주입해야합니다. 그래서 추가 다음 줄이 문제를 해결 할 수 있습니다 : 내가 솔루션을 찾고 몇 시간 후

public class AddressPresenterTest { 
    @Mock 
    StaticDatabaseHelper mockedDatabaseHelper; 
    ...