2013-04-10 23 views
7

ile aktivitesini test ederken SQLite-Database alaylıyorum Geçtiğimiz birkaç gün içinde roboguice, robolectric ve mockito ile oynamaya başladım. Kullanıcı adı daha hızlı girmek için bir AutoCompleteTextView içeren bir giriş ekranı ile küçük bir Android uygulaması var. AutoCompleteTextView için kullanıcı adları bir sqlite veritabanında depolanır.
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)); 
    } 
... 
} 

Ben MainActivity mockito ile veritabanını alay çalışırken, robolectric kullanarak test etmek istiyorum. Bu benim test-sınıftır: mainActivity.onCreate (null) çağrılması

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

; satır sonu bittiğinde, hata çağlayanı başlatılıyor imleç imleci = db.rawQuery (SQL_QUERY, null); Benim SQLiteDBAdapter benim getUserList-metodunun:

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

Ben Mock boşluk-yöntemlerin boş koçanları dönen ve diğer yöntemine null döndürür olduğunu, okuyun. SQLiteDBAdapter sınıfıyla alay ettiğimde, getUserList öğesinin mocked SQLiteDBAdapter öğesinde null değerini döndürmesini bekliyorum. Bana göre, orijinal yönteme niçin erişiyor? Ben hala orijinal SQLiteDBAdapter kullanıyor ve Mock değil. Bunu düzeltmek için ne yapmam gerekiyor ve nasıl çalışıyor? Fikirlerim tükendi, bu yüzden herhangi bir yardım takdir edilir.

cevap

2

DAO'yu sınamak için bir veritabanına bağlanmak, benim için hiçbir anlam ifade etmiyor. Ne test ediyorsun? Veritabanı. Neden onu ortadan kaldırıyor?

Tüm DAO testleriniz geçtiğinde ve kullanıcının bir iş birimini yerine getirmesi için hizmeti test etme zamanı geldiğinde, veritabanını hareket ettirmek mantıklıdır. DAO ve veritabanını zaten test ettiniz ve servis birimi testinizin bir entegrasyon testi olması gerekmez. Her durumda bu durumda alay etmektir.

Ne yaptığınız hakkında pek bir şey bilmiyorum, ama alay ettiğimde bunu yapmamın arabirimleri için. Sahte, istemci/testimin kullandığı arayüzle yazılan referans için bir stand-in uygulaması sağlar.

Somut bir sınıfla dalga geçmeye çalışıyorsanız, bu bağdaştırıcıyı arabirim tabanlı bir uygulama içinde sarmanızı öneririm. Daha iyi bir soyutlama olacak ve arayüzünüzle daha kolay bir zaman geçireceksiniz.

+0

Giriş Etkinliğimi test etmek istiyorum. Bu aktivite AutoCompleteTextview için bir userList almak için bir veritabanı kullanıyor. Veritabanını bir Mock ile değiştirmek istiyorum, bu yüzden Giriş-Aktivitesini (Düğmeler, vb.) Veritabanına bağımlı olmadan test edebilirim. Birkaç Düğme ve EditText'i iyi bir egzersiz yapmayı düşündüm, çünkü sadece birkaç günlüğüne robolectric ve mockito ile oynuyorum. – Frank

+0

Tamam, bu farklı - UI'yi test ediyorsunuz. Daha önce DAO'yu test ettiğinizi varsayalım, bu yüzden servis beklemeniz hakkındaki yorumlarım sizin için. – duffymo

+0

Üçüncü taraf koduyla dalga geçmek, tüm dünyadaki hisleri bana veriyor. Neden başka birinin kodunu test ediyorsun? Ve neden bir veritabanı olan ACTUALLY'in yükünü istiyorsun? DAO'ları test ettiğinizde, veritabanının veya sürücünün beklediğiniz gibi çalıştığını test etmiyorsunuz, veritabanıyla etkileşiminizin beklediğiniz gibi olduğunu test ediyorsunuz. Bu tam bir alayın ne için olduğu. Örneğin, gerçek bir DB'ye ulaşıldığında yinelenen güncellemeler ortaya çıkarılmaz, ancak genellikle beklenmez veya istenmez. Bu bir alay tarafından ortaya çıkar. Maalesef ne yapılabileceğini kontrol edemezsiniz, bu yüzden tek çözüm yoldur. –