2
respostas

[Dúvida] Como inserir dados no banco de dados antes dos testes

Bom dia a todos

Eu tava fazendo os testes, e após apagar o banco de dados, em alguns casos eu já queria ter o objeto inserido depois de apagar o db e antes dos teste e não ter que passar pela etapa de ver o teste sendo cadastrado e depois testar o objeto.

Eu queria fazer isso pois inserir diretamente tomaria menos tempo de teste e se fosse fazer o teste cadastrar o produto/usuario, isso tomaria tempo demais.

Eu tentei usar os métodos do dao, mas eles tem o problema de serem suspend, eu tentei desse jeito (esse é um file separado dos arquivos de teste):

private val usuarioLogin = "teste2"
private val emailLogin = "teste@gmail.com"
private val senhaLogin = "123456"

//numa função junto com o banco de dados
suspend fun limpaBancoDeDados(){
    val db = AppDatabase.instanciaBanco(InstrumentationRegistry.getInstrumentation().targetContext)
        db.clearAllTables()
        db.usuarioDao()
       .salva(Usuario(usuarioLogin, emailLogin, senhaLogin))
}

ou um jeito alternativo, inserindo numa funcao propria (esse vai ser o padrão)

suspend fun insereUsuarioNoDb(){
    AppDatabase
        .instanciaBanco(InstrumentationRegistry.getInstrumentation().targetContext)
        .usuarioDao()
        .salva(Usuario(usuarioLogin, emailLogin, senhaLogin))
}

E no arquivo de teste da activity

@Before
    fun preparaAmbiente() = runTest{
        limpaBancoDeDados()
        insereUsuarioNoDb()
    }
    @After
    fun finalizaTeste(){
        limpaBancoDeDados()
    }
    @Test
    fun deveRealizarOLogin_QuandoPreenchermosOsDadosDoUsuario() {
        //o método de login esta em outra pasta
        fazerLogin()
        ActivityScenario.launch(PerfilUsuarioActivity::class.java)
        checaSeOTextoAparece("teste2")
    }

Mas o método de login não está indo, não sei se adicionou certo no banco de dados (deveria ter outra função), ou se pelo fato do meu computador ter um processador meio fraco fez o login antes de inserir os dados no db (eu deveria travar a tarefa de login para inserir os dados primeiro)

2 respostas

Olá, Murilo!

Pelo que entendi, você está utilizando o método limpaBancoDeDados() para apagar o banco de dados e, em seguida, inserir um usuário utilizando o método insereUsuarioNoDb(). No entanto, você mencionou que o método de login não está funcionando corretamente e você não tem certeza se os dados foram adicionados corretamente ao banco de dados.

Uma possível solução para garantir que os dados sejam inseridos antes do login é utilizar uma função runBlocking ao invés de runTest no método preparaAmbiente(). Dessa forma, você pode garantir que a tarefa de inserir os dados seja concluída antes de prosseguir com o login. Ficaria assim:

@Before
fun preparaAmbiente() = runBlocking {
    limpaBancoDeDados()
    insereUsuarioNoDb()
}

@After
fun finalizaTeste() {
    limpaBancoDeDados()
}

@Test
fun deveRealizarOLogin_QuandoPreenchermosOsDadosDoUsuario() {
    fazerLogin()
    ActivityScenario.launch(PerfilUsuarioActivity::class.java)
    checaSeOTextoAparece("teste2")
}

Além disso, certifique-se de que a função salva() do seu DAO esteja funcionando corretamente e que os dados estejam sendo inseridos corretamente no banco de dados.

Espero que essas sugestões possam te ajudar a resolver o problema. Se tiver mais alguma dúvida, é só perguntar.

Espero ter ajudado e bons estudos!

Realmente, tem um problema ao tentar esse método de salvar direto no banco de dados, não sei o que pode estar dando de errado:

Função de cadastro de usuario direto no db (ele tá em um Kotlin File separado da classe de teste):

private val usuarioLogin = "teste2"
private val emailLogin = "teste@gmail.com"
private val senhaLogin = "123456"
suspend fun insereUsuarioNoDb(){
    AppDatabase
        .instanciaBanco(InstrumentationRegistry.getInstrumentation().targetContext)
        .usuarioDao()
        .salva(Usuario(usuarioLogin, emailLogin, senhaLogin))
}

O usuarioDao é assim:

@Dao
interface UsuarioDao {

    @Query("SELECT * FROM Usuario")
    fun buscaTodos(): Flow<List<Usuario>>

    @Insert
    suspend fun salva (usuario: Usuario)

    @Query("SELECT * FROM Usuario WHERE id = :usuarioId AND senha = :senha")
    suspend fun autentica(usuarioId:String,senha:String):Usuario?

    @Query("SELECT * FROM Usuario WHERE id = :usuarioId")
    fun buscaPorID(usuarioId: String): Flow<Usuario?>
}

E o banco de dados é assim:

@Database(
    entities = [Produto::class, Usuario::class],
    version = 3,
    exportSchema = true
)
@TypeConverters(Conversor::class)
abstract class AppDatabase:RoomDatabase() {
    abstract fun produtoDao(): TrapDAO
    abstract fun usuarioDao(): UsuarioDao

    companion object {
        @Volatile
        private lateinit var db: AppDatabase
        fun instanciaBanco(context: Context): AppDatabase {
            if (::db.isInitialized) return db
            return Room.databaseBuilder(
                context,
                AppDatabase::class.java,
                BuildConfig.DATABASE_NAME
            ).addMigrations(MIGRATION_1_2, MIGRATION_2_3)
                .build().also {
                    db = it
                }
        }
    }
}

E o estranho que nos testes manuais e o teste instrumentalizados com cadastro feito pelo emulador dão certo