2013-04-16 4 views
3

Я хочу начать использовать Robolectric и RoboGuice в моих Android-приложениях. Пока я делаю удовлетворительный прогресс, используя Robolectric, я застреваю с помощью RoboGuice. Я создал небольшое Android-приложение для экспериментов. Это только одно действие, вводящее Button и устанавливающее OnClickListener. В соответствующем тестовом классе я хочу ввести эту операцию, чтобы проверить кнопку. Я пробовал много вещей, которые я нашел по всему Интернету, но ни один из них не работал, поэтому я даю ему возможность побывать здесь. Вот код:Как вводить зависимости в класс Robolectric Test с помощью RoboGuice

MainActivity.java:

package com.example.TrialApp; 

import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import roboguice.activity.RoboActivity; 
import roboguice.inject.InjectView; 

public class MainActivity extends RoboActivity implements View.OnClickListener { 

    @InjectView(R.id.main_LoginButton) private Button loginButton; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     loginButton.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) { 
     SharedPreferences.Editor editor; 
     if (view.getId() == R.id.main_Login_Button) 
      Log.i("Login-Button pressed... ", ""); 
    } 
} 

CustomRobolectricTestRunner.java:

package com.example.TrialApp; 

import com.xtremelabs.robolectric.RobolectricTestRunner; 
import org.junit.runners.model.InitializationError; 

import java.io.File; 
public class CustomRobolectricTestRunner extends RobolectricTestRunner { 
    public CustomRobolectricTestRunner(Class testClass) throws InitializationError { 
     // defaults to "AndroidManifest.xml", "res" in the current directory 
     super(testClass, new File("TrialApp")); 
    } 
} 

MainActivity_Test.java:

package com.example.TrialApp; 

import com.google.inject.Inject; 
import com.xtremelabs.robolectric.Robolectric; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

import static org.junit.Assert.assertNotNull; 

@RunWith(CustomRobolectricTestRunner.class) 
public class MainActivity_Test { 

    @Inject MainActivity mainActivity; 
    @Inject ClassWithoutAName classWithoutAName; 

    @Before 
    public void setUp() { 

    } 

    @Test 
    public void mainActivityShouldNotBeNull() { 
     assertNotNull(mainActivity); 
    } 

    @Test 
    public void classWithoutANameShouldNotBeNull() { 
     assertNotNull(classWithoutAName); 
    } 
} 

classWithoutAName просто неактивности класс без содержания. Я добавил только для инъекции класса без активности.

Запуск Тест-класса как тесты не дает следующие ошибки:

java.lang.AssertionError 
at com.example.TrialApp.MainActivity_Test.mainActivityShouldNotBeNull(MainActivity_Test.java:33) <8 internal calls> 
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:288) <16 internal calls> 

и

java.lang.AssertionError 
at com.example.TrialApp.MainActivity_Test.classWithoutANameShouldNotBeNull(MainActivity_Test.java:38) <8 internal calls> 
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:288) <16 internal calls> 

Очевидно, что-то не хватает. Инъекция в MainActivity отлично работает, и приложение запущено.
Почему такая же модель инъекционных зависимостей в Robolectric-Testclass не работает? Где отсутствует ссылка?
Спасибо

ответ

1

После прочтения некоторых статей и нитей я нашел частичное решение. Я до сих пор не нашел способ внедрить UI-элементы в testclass, но я узнал, как вводить не-UI-элементы в testclass. Хитрость заключается в реализации «RobolectricTestModule», расширяющего AbstractModule. Связи, сделанные в модулях, объявленных в roboguice.xml, не присутствуют в тестовой среде, поэтому нам нужно объявить привязки для тестовой среды в этом дополнительном модуле. В настроенном Testrunner мы заменяем DefaultRoboModule новым RobolectricTestModule.
ClassWithoutAName.java:

package com.example.TrialApp; 

public class ClassWithoutAName { 

    private String string; 

    public ClassWithoutAName(String string) { 
     this.string = string; 
    } 

    public String getString() { 
     return string; 
    } 
} 

ClassWithoutANameProvider.java

package com.example.TrialApp.GuiceModules; 

import com.example.TrialApp.ClassWithoutAName; 
import com.google.inject.Provider; 

public class ClassWithoutANameProvider implements Provider<ClassWithoutAName> { 
    @Override 
    public ClassWithoutAName get() { 
     return new ClassWithoutAName("testString"); 
    } 
} 

ClassWithOutANameModule.java

package com.example.TrialApp.GuiceModules; 

import com.example.TrialApp.ClassWithoutAName; 
import com.google.inject.AbstractModule; 

public class ClassWithOutANameModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(ClassWithoutAName.class).toProvider(ClassWithoutANameProvider.class); 
    } 
} 

RobolectricTestModule.java

package com.example.TrialApp.GuiceModules; 

import com.example.TrialApp.WeirdThings; 
import com.google.inject.AbstractModule; 

public class RobolectricTestModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(ClassWithoutAName.class).toProvider(ClassWithoutANameProvider.class); 
    } 
} 

CustomRobolectricTestRunner.java

package com.example.TrialApp; 

import android.app.Application; 
import com.example.TrialApp.GuiceModules.RobolectricTestModule; 
import com.xtremelabs.robolectric.Robolectric; 
import com.xtremelabs.robolectric.RobolectricTestRunner; 
import org.junit.runners.model.InitializationError; 
import roboguice.RoboGuice; 

import java.io.File; 

public class CustomRobolectricTestRunner extends RobolectricTestRunner { 

    public CustomRobolectricTestRunner(Class testClass) throws InitializationError { 
     // defaults to "AndroidManifest.xml", "res" in the current directory 
     super(testClass, new File("TrialApp")); 
    } 

    @Override 
    public void prepareTest(Object test) { 
     Application application = (Application) Robolectric.application; 

     RoboGuice.setBaseApplicationInjector(application, RoboGuice.DEFAULT_STAGE, 
       RoboGuice.newDefaultRoboModule(application), new RobolectricTestModule()); 

     RoboGuice.getInjector(application).injectMembers(test); 
    } 
} 

То это для не-UI-элементов.

Смежные вопросы