Skip to content

Commit

Permalink
Added a helper class for mocking firebase data for Droidcon-Boston#138.
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamMc331 committed Feb 2, 2019
1 parent faf7cda commit f312106
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 24 deletions.
2 changes: 2 additions & 0 deletions Droidcon-Boston/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ dependencies {
final threeTenAbp = '1.0.5'
final recyclerRefreshLayout = '2.0.5'
final mockitoCore = '2.23.4'
final archCore = '2.0.0'
//endregion

//region Dependencies
Expand All @@ -112,6 +113,7 @@ dependencies {
testImplementation "junit:junit:$junit"
testImplementation "org.threeten:threetenbp:$threeTen"
testImplementation "org.mockito:mockito-core:$mockitoCore"
testImplementation "androidx.arch.core:core-testing:$archCore"

// Support
implementation "androidx.appcompat:appcompat:$appCompat"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ class Schedule {
fun getSpeakerString(): String? = speakerNames.joinToString(", ")
}

class ScheduleDetail(val listRow: ScheduleRow) {

var speakerBio: String = ""
var twitter: String = ""
var linkedIn: String = ""
data class ScheduleDetail(
val listRow: ScheduleRow,
var speakerBio: String = "",
var twitter: String = "",
var linkedIn: String = "",
var facebook: String = ""

) {
val id: String get() = listRow.id
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,22 @@ import com.google.firebase.database.FirebaseDatabase
open class FirebaseHelper private constructor() {

private val database: FirebaseDatabase = FirebaseDatabase.getInstance()
private val mainDatabase: DatabaseReference
val eventDatabase: DatabaseReference
val speakerDatabase: DatabaseReference
val aboutDatabase: DatabaseReference
val faqDatabase: DatabaseReference
val cocDatabase: DatabaseReference
val volunteerDatabase: DatabaseReference
private val mainDatabase: DatabaseReference = database.reference

init {
open val eventDatabase: DatabaseReference =
mainDatabase.child("conferenceData").child("events")

open val speakerDatabase: DatabaseReference =
mainDatabase.child("conferenceData").child("speakers")

open val aboutDatabase: DatabaseReference = mainDatabase.child("about")
open val faqDatabase: DatabaseReference = mainDatabase.child("faq")
open val cocDatabase: DatabaseReference = mainDatabase.child("conductCode")
open val volunteerDatabase: DatabaseReference = mainDatabase.child("volunteers")

init {
// Enable disk persistence, https://firebase.google.com/docs/database/android/offline-capabilities
this.database.setPersistenceEnabled(true)
this.mainDatabase = database.reference
this.eventDatabase = mainDatabase.child("conferenceData").child("events")
this.speakerDatabase = mainDatabase.child("conferenceData").child("speakers")
this.volunteerDatabase = mainDatabase.child("volunteers")
this.aboutDatabase = mainDatabase.child("about")
this.faqDatabase = mainDatabase.child("faq")
this.cocDatabase = mainDatabase.child("conductCode")
}

private object Holder {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.mentalmachines.droidcon_boston.firebase

import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener
import com.mentalmachines.droidcon_boston.data.FirebaseDatabase
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mockito.*

/**
* A robot class that can be used to extract out firebase functionality from the tests.
*
* Mainly we can use this to extract mocking.
*/
class FirebaseHelperRobot(mockFirebaseHelper: FirebaseHelper) {
private val mockSpeakerReference = mock(DatabaseReference::class.java)

init {
`when`(mockFirebaseHelper.speakerDatabase).thenReturn(mockSpeakerReference)
`when`(mockSpeakerReference.orderByChild(anyString())).thenReturn(mockSpeakerReference)
}

fun mockSpeakers(speakers: List<FirebaseDatabase.EventSpeaker>): FirebaseHelperRobot {
val speakerSnapshots = speakers.map { speaker ->
val mockSnapshot = mock(DataSnapshot::class.java)
`when`(mockSnapshot.getValue(FirebaseDatabase.EventSpeaker::class.java)).thenReturn(
speaker
)
return@map mockSnapshot
}

val mockSnapshot = mock(DataSnapshot::class.java)
`when`(mockSnapshot.children).thenReturn(speakerSnapshots)

doAnswer {
val valueEventListener = it.arguments.first() as ValueEventListener
valueEventListener.onDataChange(mockSnapshot)
return@doAnswer null
}.`when`(mockSpeakerReference).addValueEventListener(any(ValueEventListener::class.java))

return this
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.mentalmachines.droidcon_boston.views.detail

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener
import com.mentalmachines.droidcon_boston.data.FirebaseDatabase
import com.mentalmachines.droidcon_boston.data.Schedule
import com.mentalmachines.droidcon_boston.data.UserAgendaRepo
import com.mentalmachines.droidcon_boston.firebase.FirebaseHelper
import com.mentalmachines.droidcon_boston.firebase.FirebaseHelperRobot
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.mock
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mockito.*

class AgendaDetailViewModelTest {
private val mockAgendaRepo = mock(UserAgendaRepo::class.java)
Expand All @@ -16,19 +24,26 @@ class AgendaDetailViewModelTest {
private val startTime = "2018-03-26T15:00:00.000Z"
private val endTime = "2018-03-26T15:45:00.000Z"
private val scheduleId = "Schedule ID"
private val speakerNames = listOf("John", "Bob")
private val primarySpeakerName = "John"
private val secondarySpeakerName = "Bob"
private val speakerNames = listOf(primarySpeakerName, secondarySpeakerName)

private val scheduleRow = Schedule.ScheduleRow(
talkTitle = talkTitle,
room = talkRoom,
startTime = startTime,
endTime = endTime,
id = scheduleId,
speakerNames = speakerNames
speakerNames = speakerNames,
primarySpeakerName = primarySpeakerName
)

private val viewModel = AgendaDetailViewModel(scheduleRow, mockAgendaRepo, mockFirebaseHelper)

@JvmField
@Rule
val instantTaskExecutor = InstantTaskExecutorRule()

@Test
fun getTalkTitle() {
assertEquals(talkTitle, viewModel.talkTitle)
Expand Down Expand Up @@ -63,4 +78,15 @@ class AgendaDetailViewModelTest {
fun bookmarkedWithoutSession() {
assertFalse(viewModel.isBookmarked)
}

@Test
fun loadData() {
val eventSpeaker = FirebaseDatabase.EventSpeaker(name = primarySpeakerName)
FirebaseHelperRobot(mockFirebaseHelper).mockSpeakers(listOf(eventSpeaker))

viewModel.loadData()

val scheduleDetail = eventSpeaker.toScheduleDetail(scheduleRow)
assertEquals(scheduleDetail, viewModel.scheduleDetail.value)
}
}

0 comments on commit f312106

Please sign in to comment.