Negli ultimi giorni ho iniziato a giocare con roboguice, robolectric e mockito. Ho una piccola applicazione Android con una schermata di accesso contenente un AutoCompleteTextView per inserire più velocemente il nome utente. I nomi utente per AutoCompleteTextView sono memorizzati in un database SQLite.
Mocking del database SQLite durante il test dell'attività con 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));
}
...
}
Voglio testare MainActivity utilizzando robolectric, cercando di prendere in giro il database con Mockito. Questo è il mio test-classe:
@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);
}
}
Calling mainActivity.onCreate (null); sta iniziando l'errore-cascata, che termina in linea cursore Cursore = db.rawQuery (SQL_QUERY, null); della mia getUserList-metodo nella mia SQLiteDBAdapter:
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;
}
ho letto, che un Mock sta tornando mozziconi vuoti del vuoto-metodi, e restituisce un valore nullo su qualsiasi altro metodo. Dato che sto prendendo in giro la classe SQLiteDBAdapter, mi aspetto che chiamando getUserList sul mio SQLiteDBAdapter deriso restituisca null. Non è abbastanza chiaro per me, perché sta accedendo al metodo originale. Immagino che stia ancora usando l'originale SQLiteDBAdapter e non il Mock. Cosa devo fare per risolvere il problema e come funziona? Ho finito le idee, quindi ogni aiuto è apprezzato.
Voglio testare la mia attività di accesso. Questa attività utilizza un database per ottenere una lista utenti per la vista AutoCompleteText. Voglio sostituire il database con un Mock, così posso testare l'attività di login (pulsanti, ecc.) Senza dipendere dal database. Ho considerato un buon esercizio provare alcuni pulsanti e EditText, dato che sto giocando con robolectric e mockito solo per pochi giorni. – Frank
OK, è diverso: stai testando l'interfaccia utente. Immagino che tu abbia già testato il DAO, quindi i miei commenti sul servizio sono validi per te. – duffymo
Mocking codice di terze parti ha tutto il senso del mondo per me. Perché dovresti testare il codice di qualcun altro? E perché vuoi il sovraccarico di ACTUALMENTE avere un database. Quando si testano i DAO non si sta verificando che il database o il suo driver funzioni come previsto, si sta verificando che l'interazione con il database sia come previsto. Questo è esattamente ciò per cui è una finta. ad esempio, gli aggiornamenti duplicati non sono scoperti quando si colpisce un DB reale, ma in genere non sono previsti o richiesti. Questo è scoperto da una finta. Sfortunatamente non puoi controllare ciò che è mockable, quindi l'astrazione è l'unico modo. –