Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在使用Robolectric测试活动时模拟SQLite数据库_Android_Mockito_Robolectric_Roboguice - Fatal编程技术网

Android 在使用Robolectric测试活动时模拟SQLite数据库

Android 在使用Robolectric测试活动时模拟SQLite数据库,android,mockito,robolectric,roboguice,Android,Mockito,Robolectric,Roboguice,在过去的几天里,我开始和roboguice、robolectric和mockito一起玩。我有一个小的Android应用程序,它的登录屏幕包含一个AutoCompleteTextView,可以更快地输入用户名。AutoCompleteTextView的用户名存储在sqlite数据库中。 public class MainActivity extends RoboActivity implements View.OnClickListener { @InjectView(R.id.startScr

在过去的几天里,我开始和roboguice、robolectric和mockito一起玩。我有一个小的Android应用程序,它的登录屏幕包含一个AutoCompleteTextView,可以更快地输入用户名。AutoCompleteTextView的用户名存储在sqlite数据库中。

public class MainActivity extends RoboActivity implements View.OnClickListener {
@InjectView(R.id.startScreen_Login_Button) private Button loginButton;
@InjectView(R.id.startScreen_Cancel_Button) private Button cancelButton;
@InjectView(R.id.startScreen_forgotPwd_TextView) private TextView forgotPWTextView;
@InjectView(R.id.startScreen_Username_AutoCompleteTextView) private AutoCompleteTextView loginUsernameAutoCompleteTextView;
@InjectView(R.id.startScreen_Password_EditText) private EditText loginPasswordEditText;
@Inject private SharedPreferences sharedPreferences;
@Inject SQLiteDBAdapter dbAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    loginButton.setOnClickListener(this);
    cancelButton.setOnClickListener(this);
    forgotPWTextView.setOnClickListener(this);

    // Creating List for startScreen_Username_AutoCompleteTextView
    List<User> userList = dbAdapter.getUserList();
    ListIterator<User> it = userList.listIterator();
    List<String> userStringList = new ArrayList<String>();
    User user;
    while (it.hasNext()) {
        user = it.next();
        userStringList.add(user.getName());
    }

    loginUsernameAutoCompleteTextView.setAdapter(new ArrayAdapter<String>(this, R.layout.select_page_row, userStringList));
    }
...
}
调用mainActivity.onCreate(null);正在启动错误级联,以Cursor Cursor=db.rawQuery(SQL\u QUERY,null)行结束;我的SQLiteDBAdapter中的getUserList方法的名称:

public List<User> getUserList() {
    SQLiteDatabase db = getReadableDatabase();
    List<User> userList = new ArrayList<User>();

    String SQL_QUERY = "SELECT * FROM User;";
    Cursor cursor = db.rawQuery(SQL_QUERY, null);
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
        User user = new User();
        user.setUserUUID(cursor.getString(0));
        user.setName(cursor.getString(1));
        user.setPassword(cursor.getString(2));
        user.setDateOfBirth(cursor.getString(3));
        user.setStaffNumber(cursor.getString(4));
        user.setActive(cursor.getInt(5));
        user.setUserClass(cursor.getInt(6));
        userList.add(user);
        cursor.moveToNext();
    }
    cursor.close();
    db.close();
    return userList;
}
public List getUserList(){
SQLiteDatabase db=getReadableDatabase();
List userList=new ArrayList();
String SQL_QUERY=“SELECT*FROM User;”;
Cursor Cursor=db.rawQuery(SQL\u查询,null);
cursor.moveToFirst();
而(!cursor.isAfterLast()){
用户=新用户();
user.setUserUUID(cursor.getString(0));
user.setName(cursor.getString(1));
user.setPassword(cursor.getString(2));
user.setDateOfBirth(cursor.getString(3));
user.setStaffNumber(cursor.getString(4));
user.setActive(cursor.getInt(5));
user.setUserClass(cursor.getInt(6));
添加(用户);
cursor.moveToNext();
}
cursor.close();
db.close();
返回用户列表;
}

我读到,Mock正在返回void方法的空存根,并且在任何其他方法上返回null。在模拟SQLiteDBAdapter类时,我希望在模拟的SQLiteDBAdapter上调用getUserList会返回null。我不太清楚他为什么访问原始方法。我猜它仍然在使用原始的SQLiteDBAdapter,而不是Mock。我要怎么做才能解决这个问题,它是如何工作的?我没有主意了,所以非常感谢您的帮助。

模拟数据库来测试DAO对我来说毫无意义。你在测试什么?数据库。为什么要消除它

一旦您的所有DAO测试都通过了,并且是时候测试用户使用它来完成一个工作单元的服务了,模拟数据库就有意义了。您已经测试了DAO和数据库,您的服务单元测试不必是集成测试。在那种情况下,千万别开玩笑

我不知道你在嘲笑什么,但当我嘲笑它时,是为了我自己制作的界面。mock为我的客户机/测试正在使用的接口类型引用提供了一个替代实现


如果您试图模拟一个具体的类,我建议将该适配器包装在基于接口的实现中。这将是一个更好的抽象,您可以更轻松地模拟界面。

我想测试我的登录活动。此活动使用数据库获取AutoCompleteTextview的用户列表。我想用一个Mock替换数据库,这样我就可以在不依赖数据库的情况下测试登录活动(按钮等)。我认为测试一些按钮和编辑文本是一个很好的练习,因为我只是在玩robolectric和mockito几天。我假设您已经测试了DAO,所以我对该服务的评论对您来说是正确的。对我来说,模仿第三方代码是非常有意义的。你为什么要测试别人的代码?为什么您想要实际拥有一个数据库的开销呢。当您测试DAO时,您并不是在测试数据库或其驱动程序是否按预期工作,而是在测试您与数据库的交互是否如预期的那样。这正是模仿的目的。例如,当碰到一个真正的数据库时,重复的更新不会被发现,但通常不是预期的或想要的。这是由一个模拟发现的。不幸的是,你无法控制什么是可模仿的,所以抽象是唯一的方法。这很公平,但我想你不是说测试第三方数据库。服务对您不能直接访问任何第三方数据库。你要测试的是你的数据库。我假设您将测试这些(无模拟),然后在对使用它们的服务进行单元测试时模拟它们。
public List<User> getUserList() {
    SQLiteDatabase db = getReadableDatabase();
    List<User> userList = new ArrayList<User>();

    String SQL_QUERY = "SELECT * FROM User;";
    Cursor cursor = db.rawQuery(SQL_QUERY, null);
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
        User user = new User();
        user.setUserUUID(cursor.getString(0));
        user.setName(cursor.getString(1));
        user.setPassword(cursor.getString(2));
        user.setDateOfBirth(cursor.getString(3));
        user.setStaffNumber(cursor.getString(4));
        user.setActive(cursor.getInt(5));
        user.setUserClass(cursor.getInt(6));
        userList.add(user);
        cursor.moveToNext();
    }
    cursor.close();
    db.close();
    return userList;
}