Obtenha o contexto do projeto de teste no caso de teste Android junit

107

Alguém sabe como você pode obter o contexto do projeto Teste no caso de teste do Android junit (estende AndroidTestCase).

Nota: O teste NÃO é um teste de instrumentação.

Observação 2: preciso do contexto do projeto de teste, não do contexto do aplicativo real que é testado.

Preciso disso para carregar alguns arquivos de ativos do projeto de teste.

peceps
fonte
Por que você não pode simplesmente usar InstrumentationTestCase?
yorkw
1
Porque estou testando serviços, não UI.
peceps
1
Há uma resposta melhor encontrada aqui: [Usando AndroidTestCase em vez de um teste JUnit] [1] [1]: stackoverflow.com/questions/3170706/…
Jaime Botero

Respostas:

135

Há uma nova abordagem com a Biblioteca de Suporte de Teste do Android (atualmente androidx.test:runner:1.1.1). Exemplo atualizado de Kotlin:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

    @Before
    fun setup() {
        instrumentationContext = InstrumentationRegistry.getInstrumentation().context
    }

    @Test
    fun someTest() {
        TODO()
    }
}

Se você também quiser executar o contexto do aplicativo:

InstrumentationRegistry.getInstrumentation().targetContext

Exemplo de execução completa: https://github.com/fada21/AndroidTestContextExample

Veja aqui: Qual é a diferença entre getTargetContext () e getContext (em InstrumentationRegistry)?

fada21
fonte
Finalmente, uma resposta sobre como usar JUnit4 com InstrumentationTest. Depois de horas de pesquisa. Tenho que amar o desenvolvimento do Android.
Fabian Zeindl
1
Agradável! tx (observe que há um erro de digitação no membro da sua classe)
Greg
1
Alguém poderia ajudar sobre quais dependências precisam ser adicionadas no arquivo gradle para que isso funcione?
Greg
1
Não se esqueça de adicionar compile "com.android.support.test:runner:1.0.1"ao seu gradle
egorikem
2
Está obsoleto, use em InstrumentationRegistry.getInstrumentation().contextvez disso.
Allan Veloso
37

Depois de alguma pesquisa, a única solução de trabalho parece ser a que yorkw já apontou. Você teria que estender InstrumentationTestCase e então você pode acessar o contexto de seu aplicativo de teste usando getInstrumentation (). GetContext () - aqui está um breve trecho de código usando as sugestões acima:

public class PrintoutPullParserTest extends InstrumentationTestCase {

    public void testParsing() throws Exception {
        PrintoutPullParser parser = new PrintoutPullParser();
        parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
    }
}
AgentKnopf
fonte
7
Sim, mas parece bobo que o Android não forneça acesso ao contexto do projeto de teste em testes JUnit simples. O contexto está lá em AndroidTestCase.mTestContext, mas é privado. Não vejo por quê.
peceps
@peceps Full Ack - mas é assim que é e eu também não gosto;)
AgentKnopf
25

Como você pode ler no código-fonte AndroidTestCase , o getTestContext()método está oculto.

/**
 * @hide
 */
public Context getTestContext() {
    return mTestContext;
}

Você pode ignorar a @hideanotação usando reflexão.

Basta adicionar o seguinte método em AndroidTestCase:

/**
 * @return The {@link Context} of the test project.
 */
private Context getTestContext()
{
    try
    {
        Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
        return (Context) getTestContext.invoke(this);
    }
    catch (final Exception exception)
    {
        exception.printStackTrace();
        return null;
    }
}

Em seguida, ligue getTestContext()quando quiser. :)

Timothée Jeannin
fonte
2
Funcionou perfeitamente para mim e carrego os recursos usando o Contexto de AndroidTestCase por meio deste método ou ActivityInstrumentationTestCase2.getInstrumentation () .getContext () then getResources () .getAssets ()
Andrew Mackenzie
Você pode especular por que eles o esconderam? Se usarmos essa técnica, eles poderiam remover o método em uma versão posterior (quebrando nosso código de teste)?
Andrew Shepherd
1
Eu recebojava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage
4

Atualização: AndroidTestCase esta classe foi descontinuada no nível de API 24. Use em seu InstrumentationRegistrylugar. Novos testes devem ser escritos usando a Android Testing Support Library. Link para o anúncio

Você deve estender de AndroidTestCase em vez de TestCase.

Visão geral da classe AndroidTestCase
Estenda isso se precisar acessar recursos ou outras coisas que dependem do contexto de atividade.

AndroidTestCase - Desenvolvedores Android

Eslamb
fonte
4

Se quiser entender o contexto com Kotlin e Mockito, você pode fazer isso da seguinte maneira:

val context = mock(Context::class.java)

Espero que ajude você

Juanes30
fonte
ficando nulo no contexto?
Deven
E não se esqueça de anotar sua classe de teste com @RunWith (MockitoJUnitRunner :: class)
USMAN osman
2

Esta é a maneira correta de obter o Contexto. Outros métodos já estão obsoletos

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context
tomrozb
fonte
2
import androidx.test.core.app.ApplicationProvider;

    private Context context = ApplicationProvider.getApplicationContext();
Eoinzy
fonte
1

Para aqueles que encontrarem esses problemas ao criar testes automatizados, você deve fazer o seguinte:

    Context instrumentationContext;

    @Before
    public void method() {

        instrumentationContext = InstrumentationRegistry.getInstrumentation().getContext();

        MultiDex.install(instrumentationContext);
    }
Sebastien FERRAND
fonte
0

As outras respostas estão desatualizadas. Agora, sempre que você estende o AndroidTestCase, há o objeto mContext Context que você pode usar.

Yoni Keren
fonte