【问题标题】:JUnit testing on class with firebase使用 firebase 对类进行 JUnit 测试
【发布时间】:2017-04-05 08:04:57
【问题描述】:

我正在尝试 JUnit 测试这个类:

public class WeekListActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private ArrayList<String> weekList = new ArrayList<>();
    private ArrayAdapter<String> adapter;


    ListView weekListView;
    Button AddWeekButton;
    EditText InsertWeekEditText;
    String weekNumber;
    String subjectName;
    String subjectCode;
    User user;

    DatabaseReference mDatabase;
    DatabaseReference mRef;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_week_list);
        FirebaseApp.initializeApp(this);

        FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
        FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();

        Intent moveToDetailIntent = this.getIntent();
        subjectName = moveToDetailIntent.getExtras().getString("Subject");
        subjectCode = moveToDetailIntent.getExtras().getString("Fagkode");

        mDatabase = FirebaseDatabase.getInstance().getReference().child("Studentfag").child(subjectCode).child("Week");
        mRef = FirebaseDatabase.getInstance().getReference().child("Users").child(firebaseUser.getUid()).child("User info");

        weekListView = (ListView) findViewById(R.id.WeekListView);
        AddWeekButton = (Button) findViewById(R.id.AddWeekButton);
        InsertWeekEditText = (EditText) findViewById(R.id.InsertWeek);

        String userID = firebaseUser.getUid();
        mRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                user = dataSnapshot.getValue(User.class);
                if (user.isStudent){
                    View a = weekListView;
                    a.setMinimumHeight(80);
                    View b = AddWeekButton;
                    b.setVisibility(View.GONE);
                    View c = InsertWeekEditText;
                    c.setVisibility(View.GONE);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, weekList);
        weekListView.setAdapter(adapter);
        weekListView.setOnItemClickListener(this);
        AddWeekButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                weekNumber= InsertWeekEditText.getText().toString();
                mDatabase.child(weekNumber).child("id").setValue(weekNumber);
            }
        });

        mDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                String week = dataSnapshot.getKey().toString();
                    weekList.add("Week: " + week);
                    adapter.notifyDataSetChanged();
                }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            //Urelevante metoder for oss.
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });

    }

问题是,当我在我的设置方法中构建一个新活动时,它会抱怨,因为这句话:

mRef = FirebaseDatabase.getInstance().getReference().child("Users").child(firebaseUser.getUid()).child("User info");

当我们没有 firebase 用户时,无法构建。 因此,我试图在我的测试类中模拟一个 firebaseuser。问题是,我怎样才能告诉班级它应该在onCreate 中使用模拟的firebaseuser?有没有办法“发送”模拟对象?谢谢!

我的设置方法的开始:

  @Before
public void setUp() throws Exception {

    Intent i = new Intent();
    i.putExtra("Subject", "Matematikk 1");
    i.putExtra("Fagkode", "TMA4100");

    FirebaseUser mockFirebaseUser = mock(FirebaseUser.class);
    when(mockFirebaseUser.getUid()).thenReturn("uTZpVPPz8NT2LOvP4ufjs1L6r3P2");

    Activity activity = Robolectric.buildActivity(WeekListActivity.class).withIntent(i).create().get();

}

【问题讨论】:

  • 就我个人而言,我发现 Robolectric 不适用于 Firebase API。在没有 Robolectric 尝试直接调用 FirebaseDatabase 的帮助下,我只能完全模拟所有 API,例如 FirebaseDatabase。
  • 我也很好奇你为什么要调用 FirebaseApp.initializeApp(this)。如果您将 Firebase 与 gradle 插件和 google-services.json 集成,则不必这样做。

标签: android firebase junit mocking robolectric


【解决方案1】:

像往常一样,我建议大家不要混合表示和存储代码。这是另一个话题的问题。

这里是如何实现你想要的东西的诀窍。 一、提取Firebase初始化方法并提供FirebaseAuth

 @VisibleForTest
 @NonNull
 FirebaseAuth initAndReturnFirebaseAuth() {
     FirebaseApp.initializeApp(this);
     FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 }

其次,创建测试活动并覆盖此方法:

public class TestWeekListActivity extends WeekListActivity {
    @Override
    @NonNull
    FirebaseAuth initAndReturnFirebaseAuth() {
       FirebaseAuth authMock = mock(FirebaseAuth.class);
       when(authMock.getCurrentUser()).thenReturn(mockFirebaseUser);
       return authMock;
    }
}

然后在测试中使用测试活动而不是您的实际活动。

希望对你有帮助!

【讨论】:

  • 我面临的问题是我不知道如何创建“mockFirebaseUser”
  • @Mambazo 你能解决这个问题吗,如果是的话,你能把你的答案贴在这里
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多