2017-09-12 34 views
1

我想在Android開發人員的SQLite數據庫中爲我的訪問器類編寫單元測試。然而,當我運行測試類,我得到以下錯誤:Android的SQLiteOpenHelper測試類

java.lang.RuntimeException: Method getWritableDatabase in android.database.sqlite.SQLiteOpenHelper not mocked. See http://g.co/androidstudio/not-mocked for details. 

at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java) 
at com.example.jack.app4.helper.CharityHelper.insertData(CharityHelper.java:54) 
at helper.TestCharityHelper.testInsertAndSelectAll(TestCharityHelper.java:63) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117) 
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42) 
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262) 
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 

的問題是,我在測試的onSetup創建CharityHelper的實例爲空,但我不能工作如何解決這個問題。任何幫助將不勝感激。

我的訪問器類測試:

/** 
* Accessor class for Charity Table. 
* 
* Created by Jack on 07/09/2017. 
*/ 

public class CharityHelper extends SQLiteOpenHelper { 

    private static final String DATABASE_NAME = "Example.db"; 
    private static final String TABLE_NAME = "Charity"; 
    private static final String ID = "id"; 
    private static final String CHARITY_NAME = "charityName"; 
    private static final String CHARITY_NUMBER = "charityNumber"; 
    private static final String POSTCODE= "postCode"; 
    private static final String CHARITY_TYPE= "charityType"; 


    public CharityHelper(Context context) { 
     super(context, DATABASE_NAME, null , 1); 
//  SQLiteDatabase db = this.getWritableDatabase(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL("CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, CHARITY_NAME TEXT, CHARITY_NUMBER INTEGER, POSTCODE VARCHAR, GENRE VARCHAR)"); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int i, int i1) { 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
     onCreate(db); 
    } 


    /** 
    * Insert record into charity table. 
    * @param charity - charity to be inserted 
    * @return boolean - whether insert was successful or not. 
    */ 
    public boolean insertData(Charity charity) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues contentValues = new ContentValues(); 
     contentValues.put(CHARITY_NAME, charity.getName()); 
     contentValues.put(CHARITY_NUMBER, charity.getNumber()); 
     contentValues.put(POSTCODE, charity.getPostcode()); 
     contentValues.put(CHARITY_TYPE, charity.getCharityType().toString()); 

     long result = db.insert(TABLE_NAME, null, contentValues); 

     return result != -1; 
    } 


    /** 
    * Method to return list of all charities in db. 
    * Will return empty list if no record found. 
    * @return List<Charity> 
    */ 
    public List<Charity> selectAll() { 
     SQLiteDatabase db = this.getReadableDatabase(); 

     Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null); 

     return getCharitiesListFromCursor(cursor); 
    } 


    /** 
    * Method to return list of all charities in db of the charity type passed in. 
    * Will return empty list if no record found. 
    * @return List<Charity> 
    */ 
    public List<Charity> selectByCharityType(Charity.CharityType charityType) { 
     SQLiteDatabase db = this.getReadableDatabase(); 

     Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE genre = ?", new String[] {charityType.toString()}); 

     return getCharitiesListFromCursor(cursor); 
    } 

    /** 
    * Takes cursor from db query and convert into list of charities. 
    * @param cursor - passed in cursor 
    * @return List Charity 
    */ 
    private List<Charity> getCharitiesListFromCursor(Cursor cursor) { 
     List<Charity> charityList = new ArrayList<>(); 

     while (cursor.moveToNext()) { 
      charityList.add(new Charity(
        cursor.getString(cursor.getColumnIndex(CHARITY_NAME)), 
        cursor.getLong(cursor.getColumnIndex(CHARITY_NUMBER)), 
        cursor.getString(cursor.getColumnIndex(POSTCODE)), 
        Charity.CharityType.valueOf(cursor.getString(cursor.getColumnIndex(CHARITY_TYPE))) 
      )); 
     } 
     return charityList; 
    } 

} 

我的測試類:

/** 
* Test class for Charity Helper 
* Created by Jack on 10/09/2017. 
*/ 

@RunWith(MockitoJUnitRunner.class) 
public class TestCharityHelper { 

    private Charity testCharity; 
    private CharityHelper charityHelper; 

    private final String testCharityName = "testName"; 
    private final Long testCharityNumber = 1234L; 
    private final String testCharityPostcode = "CO10 8NP"; 
    private final Charity.CharityType testCharityType = Charity.CharityType.ANIMAL; 

    @Mock 
    SQLiteDatabase dbMock; 

    @Mock Context mockContext; 

    @Before 
    public void onSetup() { 

     charityHelper = new CharityHelper(mockContext); 
     testCharity = new Charity(testCharityName,testCharityNumber,testCharityPostcode,testCharityType); 
    } 

    @After 
    public void tearDown() throws Exception{ 
     charityHelper.close(); 
//  super.tearDown(); 
    } 


    @Test 
    public void testInsertAndSelectAll() { 
     charityHelper.insertData(testCharity); 

     List<Charity> returnedCharityList = charityHelper.selectAll(); 

     assertTrue(returnedCharityList.contains(testCharity)); 

    } 
} 

回答

0

在你的設置方法,你需要使用RenamingDelegatingContext()方法返回的上下文。您還需要擴展AndroidTestCase類

public class TestCharityHelper extends AndroidTestCase{ 

. 
. 
private RenamingDelegatingContext mockContext; 


public void setUp() throws Exception { 
    super.setUp(); 


    final String prefix = "test"; 
    mockContext = new RenamingDelegatingContext(getContext(),prefix); 

    charityHelper = new CharityHelper(mockContext); 
    testCharity = new Charity(testCharityName,testCharityNumber,testCharityPostcode,testCharityType); 
} 
+0

這樣做對您有用@Jack Wilkinson –

相關問題