2010-01-19 16 views
50

我正在編寫我的第一個Android數據庫後端,我正在努力測試創建我的數據庫。需要上下文的Android單元測試

目前我遇到的問題是獲取一個有效的Context對象傳遞給我的SQLiteOpenHelper實現。有沒有辦法在擴展TestCase的類中獲取Context對象?我想到的解決方案是在我的TestCase的setup方法中實例化Activity,然後將該Activity的Context分配給我的測試方法可以訪問的字段變量......但似乎應該有一種更簡單的方法。

感謝您的輸入!

梅西

回答

37

你可以嘗試切換到AndroidTestCase。從查看文檔看來,它似乎應該能夠爲您提供有效的上下文以傳遞給SQLiteOpenHelper。

編輯: 請記住,您可能必須在Eclipse的「Android測試項目」中設置測試,因爲測試將嘗試在模擬器(或真實設備)上執行。

+0

感謝埃裏希,這絕對是正確的道路要走。 – 2010-01-19 18:13:50

+0

當擴展AndroidTestCase,然後調用'this.getContext()'時,返回'null'。它是如何工作的?我期望返回一個與SQLite一起使用的豐富上下文 – cdaringe 2016-03-23 04:41:11

+3

AndroidTestCase現在已被棄用,建議使用InstrumentationRegistry代替。 – 2016-09-21 08:41:19

1

您應該使用ApplicationTestCase或ServiceTestCase。

4

使用AndroidTestCase:getContext()方法在我的經驗中僅給出存根上下文。對於我的測試,我在主應用程序中使用了一個空的活動,並通過它獲取Context。我還用ActivityInstrumentationTestCase2類擴展了測試套件類。似乎爲我工作。

public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity> 
    EmptyActivity activity; 
    Context mContext = null; 
    ... 
    @Before 
    public void setUp() { 
     activity = getActivity(); 
     mContext = activity; 
    } 
    ... //tests to follow 
} 

其他人都做了什麼?

1

擴展AndroidTestCase並調用AndroidTestCase:getContext()對我來說可以正常工作,並獲取Context並將其用於SQLiteDatabase。

唯一的挑剔是數據庫它創建和/或用途將是一樣的生產應用程序中使用的,所以你可能會想使用一個不同的文件名兩者

如。

public static final String NOTES_DB  = "notestore.db"; 
    public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db"; 
1

您可以從MockContext派生並返回例如MockResourcesgetResources(),在getContentResolver()有效ContentResolver等,即允許一些痛苦,一些單元測試

另一種方法是運行模擬整個Android OS的Robolectric。這些將用於系統測試:運行速度慢很多。

-1

另一種解決方案是避免使用ApplicationTestCaseAndroidTestCase或依賴於Context的任何其他類。問題的關鍵是,有沒有必要測試SQLiteORM框架,所以你可以用基本的CRUD方法創建界面:

public interface UsersManager{ 
    User createUser(String userId); 
    User getUser(String userId); 
    boolean updateUser(User user); 
    boolean deleteUser(User user); 
} 

並實行兩個版本:一個用於測試,另一個用於生產運行。爲測試版本可能與HashMap可以輕鬆實現:

public class TestUsersManager implements UsersManager{ 

    private HashMap<String, User> users = new HashMap(); 

    public User createUser(String userId){ 
    User result = new User(userId); 
    users.put(userId, user); 
    return result; 
    } 
    //... other methods 
} 

它的工作速度快(無磁盤IOSQLite情況下),不存在外部依賴性。順便說一句,這也是額外的抽象層次:對於生產代碼,您可以輕鬆地在ORM框架之間切換。

14

如果您正在使用AndroidJUnit4運行測試,您可以使用InstrumentationRegistry方法來獲取上下文:

InstrumentationRegistry.getTargetContext() - 提供目標應用程序的應用Context;

InstrumentationRegistry.getContext() - 提供該儀器包裝的Context;

+1

AndroidJUnit4.class的依賴是從哪裏來的? – Ewoks 2016-07-25 21:06:02

+3

同上需要一個更完整的例子。 – StarWind0 2017-01-16 08:16:09

0

先在(androidTest)下創建測試類。

現在使用下面的代碼:

public class YourDBTest extends InstrumentationTestCase { 

private DBContracts.DatabaseHelper db; 
private RenamingDelegatingContext context; 

@Override 
public void setUp() throws Exception { 
    super.setUp(); 
    context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_"); 
    db = new DBContracts.DatabaseHelper(context); 
} 

@Override 
public void tearDown() throws Exception { 
    db.close(); 
    super.tearDown(); 
} 

@Test 
public void test1() throws Exception { 
    // here is your context 
    context = context; 
}}