2013-04-10 36 views
7

Trong vài ngày qua, tôi bắt đầu chơi xung quanh với roboguice, robolectric và mockito. Tôi có một ứng dụng Android nhỏ với màn hình đăng nhập có chứa một AutoCompleteTextView để nhập nhanh hơn tên người dùng. Tên người dùng cho AutoCompleteTextView được lưu trữ trong một cơ sở dữ liệu sqlite.
Giả mạo cơ sở dữ liệu SQLite trong khi thử nghiệm Hoạt động với Robolectric

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

Tôi muốn kiểm tra MainActivity bằng cách sử dụng robolectric, cố gắng giả lập cơ sở dữ liệu bằng mockito. Đây là lớp thử nghiệm của tôi:

@RunWith(CustomRobolectricTestRunner.class) 
public class MainActivityTest { 

@Mock 
SQLiteDBAdapter dbAdapter; 

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

@Test 
public void shouldHaveApplicationName() throws Exception { 
    String appName = new MainActivity().getResources().getString(R.string.app_name); 
    assertThat(appName, equalTo("OperationReport")); 
} 

@Test 
public void testButtonsVisible() 
{ 
    MainActivity mainActivity = new MainActivity(); 
    mainActivity.onCreate(null); 
} 
} 

Gọi mainActivity.onCreate (null); đang bắt đầu lỗi-cascade, kết thúc trong dòng Cursor cursor = db.rawQuery (SQL_QUERY, null); của phương thức getUserList của tôi trong SQLiteDBAdapter của tôi:

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

Tôi đọc, rằng một Mock trả về các giá trị rỗng của phương thức void và trả về null trên bất kỳ phương thức nào khác. Khi tôi đang chế nhạo lớp SQLiteDBAdapter, tôi mong rằng việc gọi getUserList trên SQLiteDBAdapter giả lập của tôi trả về null. Nó không phải là khá rõ ràng với tôi, tại sao anh ta đang truy cập các phương pháp ban đầu. Tôi đoán nó vẫn đang sử dụng SQLiteDBAdapter ban đầu và không phải là Mock. Tôi phải làm gì để sửa lỗi này và nó hoạt động như thế nào? Tôi hết ý tưởng, vì vậy bất kỳ trợ giúp nào đều được đánh giá cao.

Trả lời

2

Giả mạo cơ sở dữ liệu để kiểm tra DAO không có ý nghĩa gì với tôi cả. Bạn đang thử nghiệm cái gì? Kho dữ liệu. Tại sao loại bỏ nó?

Giả mạo cơ sở dữ liệu có ý nghĩa khi bạn có tất cả các bài kiểm tra DAO của bạn và đây là lúc để kiểm tra dịch vụ mà người dùng hoàn thành một đơn vị công việc. Bạn đã kiểm tra DAO và cơ sở dữ liệu và thử nghiệm đơn vị dịch vụ của bạn không cần phải là thử nghiệm tích hợp. Bởi tất cả các phương tiện giả trong trường hợp đó.

Tôi không biết nhiều về những gì bạn đang chế giễu, nhưng khi tôi giả lập nó là giao diện của việc tạo ra. Mô hình cung cấp một triển khai thực hiện cho tham chiếu đã nhập giao diện mà máy khách/thử nghiệm của tôi đang sử dụng.

Nếu bạn đang cố gắng thử một lớp cụ thể, tôi khuyên bạn nên gói bộ điều hợp đó bên trong việc triển khai dựa trên giao diện. Nó sẽ là một trừu tượng tốt hơn và bạn sẽ có một thời gian dễ dàng hơn chế giễu giao diện của bạn.

+0

Tôi muốn kiểm tra Hoạt động đăng nhập của mình. Hoạt động này đang sử dụng cơ sở dữ liệu để lấy danh sách người dùng cho AutoCompleteTextview. Tôi muốn thay thế cơ sở dữ liệu bằng Mock, vì vậy tôi có thể kiểm tra Hoạt động đăng nhập (Nút, v.v.) mà không bị phụ thuộc vào cơ sở dữ liệu. Tôi xem xét thử nghiệm một số nút và EditText một bài tập tốt, kể từ khi tôi chơi xung quanh với robolectric và mockito chỉ trong một vài ngày. – Frank

+0

OK, điều đó khác - bạn đang thử nghiệm giao diện người dùng. Tôi sẽ giả định rằng bạn đã kiểm tra DAO, vì vậy nhận xét của tôi về dịch vụ giữ cho bạn. – duffymo

+0

Mocking mã bên thứ ba làm cho tất cả các ý nghĩa trên thế giới với tôi. Tại sao bạn lại kiểm tra mã của người khác? Và tại sao bạn muốn chi phí thực sự có cơ sở dữ liệu. Khi bạn kiểm tra DAO, bạn không thử nghiệm cơ sở dữ liệu hoặc các chức năng của trình điều khiển như bạn mong đợi, bạn đang thử nghiệm rằng sự tương tác của bạn với cơ sở dữ liệu như bạn mong đợi. Đây chính xác là một mô hình. ví dụ như bản cập nhật trùng lặp không được phát hiện khi nhấn một DB thực, nhưng thường không được mong đợi hoặc muốn. Điều này được phát hiện bởi một mô hình. Thật không may bạn không thể kiểm soát những gì là mockable, do đó trừu tượng là cách duy nhất. –

Các vấn đề liên quan