finatra/examples/twitter-clone: Testing the firebase client

86 views
Skip to first unread message

Damian Nadales

unread,
Feb 18, 2017, 6:33:45 AM2/18/17
to finatra-users
Hi,

I'm trying to figure out how to get instances of singleton classes, as explained here:

    http://stackoverflow.com/questions/42314554/finatra-examples-twitter-clone-testing-the-firebase-client

Any ideas?

Thanks in advance,
Damian.

Christopher Coco

unread,
Feb 18, 2017, 11:55:31 AM2/18/17
to Damian Nadales, finatra-users
I would highly recommend that you take a look through the User's Guide (https://twitter.github.io/finatra/user-guide/) and the myriad of tests (as they are a great example of how to do things).

The simple answer to your question is you just instantiate the class, e.g. in your test you write:

new FirebaseClient(...) and pass values for the constructor args. 

Which yes, means you need to create an HttpClient and a mapper, etc. This is normal instance instantiation -- nothing special going on here. The @Singleton annotation is information for the injector to use about how it should construct an instance for you when asked. Thus you would need to use an injector.

Since you asked about "how to get instances of singleton classes", then I'm guessing you're asking about how to use an injector since you need to construct an object graph then ask the injector for a @Singleton annotated instance.

Again, this is all documented in the User's Guide and these are central concepts to the framework. It also really helps to understand TwitterServer (since Finatra ties an object graph to a TwitterServer server) and the basics of Finagle.

We'll take the Twitter Clone feature test as a starting place:


If you read the section on Modules from the User's Guide, you'll see that we generally use them to define how the injector should construct a complex instance. In the case of the TwitterClone server, we have a FirebaseHttpClientModule: https://github.com/twitter/finatra/blob/master/examples/twitter-clone/src/main/scala/finatra/quickstart/modules/FirebaseHttpClientModule.scala which defines how to provide to the injector an instance of the FirebaseClient.

You'll notice that module extends the Finatra framework HttpClientModule (a helper class for creating HttpClients): https://github.com/twitter/finatra/blob/develop/httpclient/src/main/scala/com/twitter/finatra/httpclient/modules/HttpClientModule.scala#L29

Thus in tests, there are two ways to create an object graph. Like the TwitterCloneFeatureTest you can create a server and then get a reference to it's in injector, e.g.,

class TwitterCloneFeatureTest
  extends FeatureTest
  with Mockito {
  override val server = new EmbeddedHttpServer(new TwitterCloneServer)

  val firebaseClient = server.injector.instance[FirebaseClient]

Taking the test as a starting point, if you wanted a reference to the firebaseClient, you would ask the embedded server for a handle to the injector of the server it's wrapping. Then ask the injector for an instance of the FirebaseClient from the object graph. Since the FirebaseClient class is annotated with @Singleton, every time you repeat: server.injector.instance[FirebaseClient], it'll be the same singleton instance.

The other way in tests to create an object graph is to use the TestInjector: https://github.com/twitter/finatra/blob/master/inject/inject-app/src/test/scala/com/twitter/inject/app/TestInjector.scala constructed over a set of modules.

So in a test, you could do this:

val injector = TestInjector(FirebaseClientModule)
val firebaseClient = injector.instance[FirebaseClient]

Thanks!
-c

--
You received this message because you are subscribed to the Google Groups "finatra-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to finatra-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Damian

unread,
Feb 19, 2017, 12:36:37 PM2/19/17
to Christopher Coco, finatra-users
Hi Christopher,

Thanks a lot for your detailed answer, and the time you took to
explain this. I had gone through the documentation you referred to,
but the `TestInjector` was the missing piece of the puzzle. I got a
working test now.

I have a question though, when is the whole dependency injection
process started? By calling `TestInjector`?
>> email to finatra-user...@googlegroups.com.

Christopher Coco

unread,
Feb 20, 2017, 4:57:15 PM2/20/17
to Damian, finatra-users
Hi Damian,

When using the TestInjector, you'll see that the object graph is created over the modules in the apply method (which returns the injector): https://github.com/twitter/finatra/blob/master/inject/inject-app/src/test/scala/com/twitter/inject/app/TestInjector.scala#L16

Thanks,
-c

Reply all
Reply to author
Forward
0 new messages