Integration Tests

Important

Please see the section on including test-jar dependencies in your project: Test Dependencies.

Note

If you are calling an c.t.util.Await function on a c.t.util.Future return type in a test, it is generally considered good practice to ensure that your c.t.util.Await call includes a timeout duration, e.g., c.t.util.Await#ready.

c.t.inject.app.TestInjector

Whereas Feature Tests start a server or app under test (thereby loading its entire object graph), integration tests generally only test across a few interfaces in the system. In Finatra, we provide the c.t.inject.app.TestInjector which allows you to pass it a set of TwitterModules and Flags to construct a minimal object graph.

Important

Because TwitterModules differ from regular Guice Modules, it is important to use the c.t.inject.app.TestInjector for creating an object graph over a set of TwitterModules.

The TestInjector properly handles lifecycle execution and Flag parsing.

Manually creating a c.t.inject.Injector over a raw Guice Injector created from TwitterModules will skip both the lifecycle functions and Flag parsing of any Flag instances defined in the set of TwitterModules.

To write an integration test, extend the c.t.inject.IntegrationTest trait. Then override the injector val with your constructed instance of on a c.t.inject.Injector created from the c.t.inject.app.TestInjector.

You’ll then be able to access instances of necessary classes to execute tests.

import com.twitter.inject.Injector
import com.twitter.inject.IntegrationTest
import com.twitter.inject.app.TestInjector

class ExampleIntegrationTest extends IntegrationTest {
  override val injector: Injector =
    TestInjector(
      flags = Map("foo.flag" -> "meaningfulValue"),
      modules = Seq(ExampleModule)
    ).create

  test("MyTest#perform feature") {
    val exampleThingy = injector.instance[ExampleThingy]
    ...
  }
}

Caution

The injector is specified as a def the in c.t.inject.IntegrationTestMixin trait. If you only want to start one instance of your injector per test file make sure to override this def with a val.

bind[T] DSL

Note that the c.t.inject.app.TestInjector also supports the bind[T] DSL for overriding bound types. See the bind[T] documentation for more information.

Http Tests

If you are writing a test that has an HTTP server under test, you can also extend the c.t.finatra.http.HttpTest trait. This trait provides some common utilities for HTTP testing, specifically utilities for constructing a resolverMap flag value for setting on your server under test.

Thrift Tests

Thrift servers can be tested through a c.t.finatra.thrift.ThriftClient. The Finatra test framework provides an easy way get access to a real Finagle client for making calls to your running server in a test.

See the Feature Tests - Thrift Server section for more information on creating a Finagle Thrift client.

Additionally, your test can also extend the c.t.finatra.thrift.ThriftTest trait which provides a utility specifically for constructing a resolverMap flag value for setting on your server under test.