2013-04-10 12 views
7

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.

risposta

2

Prendere in giro un database per testare un DAO non ha alcun senso per me. Cosa stai testando? Il database Perché eliminarlo?

Il mocking del database ha senso quando si superano tutti i test DAO ed è ora di testare il servizio per consentire agli utenti di soddisfare un'unità di lavoro. Hai già testato DAO e il database e il test dell'unità di servizio non deve essere un test di integrazione. In tutti i casi deriso in quel caso.

Non so molto di quello che stai deridendo, ma quando mi burlo è per le interfacce della mia creazione. La simulazione fornisce un'implementazione stand-in per il riferimento tipizzato all'interfaccia utilizzato dal mio client/test.

Se stai provando a prendere in giro una classe concreta, ti consigliamo di inserire tale adattatore in un'implementazione basata su interfaccia. Sarà un'astrazione migliore e avrai un tempo più semplice per deridere la tua interfaccia.

+0

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

+0

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

+0

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. –