Como podemos acessar o contexto de uma aplicação no Robolectric?


112

Na verdade, preciso obter uma resposta de uma chamada de API, para isso eu solicitei Context.

Respostas:


218

Atualizar.

Basta usar para as versões 1.xe 2.x:

Robolectric.application;

E para a versão 3.x:

RuntimeEnvironment.application;

E para a versão 4.x:

  • adicione ao seu build.gradlearquivo:

    testImplementation 'androidx.test:core:1.0.0'
    
  • recupere o contexto com:

    ApplicationProvider.getApplicationContext()
    

11
Você colocou @RunWith (RobolectricTestRunner.class) para seus testes?
Eugen Martynov

4
Sim .. Eu adicionei ... mas ainda assim ele retorna nulo
user1667968

1
Eu fiz tudo o que você mencionou e ainda fico nulo. Posso estar faltando mais alguma coisa?
Moises Jimenez

13
Certifique-se também de não usar RuntimeEnvironment.applicationcódigo estático (como métodos anotados com @BeforeClass), pois o Robolectric provavelmente não será inicializado nesse ponto e o valor será null.
sfera

1
Além disso, isso faz com que o aplicativo vaze entre os testes .. o que pode não ser desejável
Chris

26

Você pode usar

RuntimeEnvironment.application

4
no RoboElectric 3.0, Roboelectric.application não existe mais, então esta é provavelmente a melhor resposta
kenyee


16

Adicionar

testImplementation "androidx.test:core-ktx:${deps.testrunner}"

E use:

private val app = ApplicationProvider.getApplicationContext()

import androidx.test.core.app.ApplicationProvider
luckyhandler

val appContext = ApplicationProvider.getApplicationContext <Context> ()
luckyhandler

2
Esta é a resposta correta com o Robolectric mais recente. Outros métodos mencionados aqui foram descontinuados ou removidos.
Gabor de

7

Para o mais recente Robolectric 4.3 a partir de agora em 2019 `

ShadowApplication.getInstance ()

`e

Roboletric.application

são ambos depreciados. Então estou usando

Context context = RuntimeEnvironment.systemContext;

para obter o contexto.


5

Para obter o contexto do aplicativo, você deve fazer o seguinte:

  1. annotate @RunWith (RobolectricTestRunner.class)
  2. RuntimeEnvironment.application.getApplicationContext ()

2

Isso funciona para mim com Robolectric 3.5.1: ShadowApplication.getInstance().applicationContext


Observe que parece que a versão 4.0 removerá esse método; melhor ficar com RuntimeEnvironment.applicationou RuntimeEnvironment.application.getApplicationContext()se estiver funcionando para você.
qix

2

A partir do lançamento 4.0-alpha-3 em 21 de julho, eles foram removidos ShadowApplication.getApplicationContext() . Fique com RuntimeEnvironment.application.getApplicationContext()para quaisquer testes anotados com @RunWith(RobolectricTestRunner::class).

Como um aparte, seu guia atual tem um exemplo de como obter recursos de string usando:

final Context context = RuntimeEnvironment.application;

(Observe que os javadocs para RuntimeEnvironmente ShadowApplicationatualmente refletem a versão não alfa 3.x.)


2

Primeiro adicione o seguinte ao seu build.gradle:

testImplementation 'androidx.test:core:1.2.0'

então use:

ApplicationProvider.getApplicationContext() as Application


2

Em alguns casos, você pode precisar do contexto do seu aplicativo em vez do contexto padrão do Robolectris. Por exemplo, se você deseja obter o nome do seu pacote. Por padrão, o Robolectric retornará o org.robolectric.defaultnome do seu pacote. Para obter o nome real do seu pacote, faça o seguinte:

build.gradle

testImplementation 'org.robolectric:robolectric:4.2.1'

Sua aula de teste:

@RunWith(RobolectricTestRunner.class)
@Config( manifest="AndroidManifest.xml")
public class FooTest {

@Test
public void fooTestWithPackageName(){
    Context context = ApplicationProvider.getApplicationContext();
    System.out.println("My Real Package Name: " + context.getPackageName());
}

}

Certifique-se de que em seu diretório de trabalho Run / Debug Configurations está definido como: $ MODULE_DIR $ insira a descrição da imagem aqui insira a descrição da imagem aqui


1

É mais seguro usar em Robolectric.getShadowApplication()vez de usar Robolectric.applicationdiretamente.


Mas e se eu precisar acessar algumas propriedades personalizadas de meu aplicativo personalizado? Parece que não consigo obter o objeto real do aplicativo de sombra.
Denis Kniazhev

@DenisKniazhev Desculpe, não posso responder isso para você. Pouco depois de começarmos a usar o Robolectric, começamos a usar o Travis como nosso CI, e eles não funcionam bem. Meu palpite é que você pode lançá-lo em seu aplicativo ou pode precisar fazer um runner personalizado para ter acesso a ele dessa forma.
Boa

Obrigado, por enquanto, acabei de me limitar aRobolectric.application
Denis Kniazhev

6
Robolectric.getShadowApplication () não está disponível
IgorGanapolsky 01 de

1

Concordo com as respostas de @EugenMartynov e @rds ....

Um exemplo rápido pode ser encontrado em Volley-Marshmallow-Release

em NetworkImageViewTest.java

// mNIV = new NetworkImageView(Robolectric.application); mNIV = new NetworkImageView(RuntimeEnvironment.application);

O link do Volley está disponível em https://android.googlesource.com/platform/frameworks/volley/+/marshmallow-release

você precisa adicionar dependências no módulo de volley no android studio como:

dependencies { testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' testCompile 'org.robolectric:robolectric:3.1.2' }


1

No seu caso, acho que você deve estar ciente do que está realmente testando. Às vezes encontrando problemas de não testável código ou código aparentemente não testável é um sinal de que talvez seu código precise ser refatorado.

Para uma resposta de chamada de API, você pode não querer testar a própria chamada de API. Pode não ser necessário testar se é possível enviar / receber informações de qualquer serviço da web arbitrário, mas sim se seu código trata e processa sua resposta de uma maneira esperada.

Nesse caso, pode ser melhor refatorar o código que você está tentando testar. Divida a análise / tratamento de resposta para outra classe que aceita um simples Stringe faça seu teste nessa classe injetando respostas de string de amostra.

Isso está mais ou menos seguindo as idéias de Responsabilidade Única e Inversão de Dependência (O S e D em SÓLIDO )


1

Ok, então eu sei que muitos outros disseram esta resposta antes e podem já estar desatualizados

    when(mockApplication.getApplicationContext()).thenReturn(RuntimeEnvironment.application);
    when(mockApplication.getFilesDir()).thenReturn(RuntimeEnvironment.application.getFilesDir());

    sharedPref = RuntimeEnvironment.application.getSharedPreferences(KEY_MY_PREF, Context.MODE_PRIVATE);
    sut = new BundleManagerImpl(mockApplication,
            processHtmlBundle, resultListener, sharedPref);

Eu obtive null, porque a parte when () foi DEPOIS da inicialização do sut. Isso pode ajudar alguns de vocês.

também eu tenho o

@RunWith(CustomRobolectricTestRunner.class)
@Config(constants = BuildConfig.class)

no começo da aula

Além disso

 when(mockApplication.getApplicationContext()).thenReturn(RuntimeEnvironment.application.getApplicationContext()); works
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.