Skip to content

Commit

Permalink
Add convenience factories to TestingServiceModule. (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
nlativy authored Feb 22, 2018
1 parent 651d9b6 commit 7384272
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 33 deletions.
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,13 @@
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>0.31</version>
<version>0.39</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth.extensions</groupId>
<artifactId>truth-java8-extension</artifactId>
<version>0.39</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
32 changes: 23 additions & 9 deletions src/main/java/com/google/acai/TestingServiceModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@

package com.google.acai;

import com.google.common.collect.ImmutableList;
import com.google.common.testing.TearDown;
import com.google.common.testing.TearDownAccepter;
import com.google.common.testing.TearDownStack;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.multibindings.Multibinder;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import javax.annotation.CheckReturnValue;
import javax.inject.Singleton;

/**
Expand All @@ -35,17 +33,33 @@
* <pre>
* class MyModule extends AbstractModule {
* {@literal @}Override protected void configure() {
* install(new TestingServiceModule() {
* {@literal @}Override protected void configureTestingServices() {
* bindTestingService(MyTestingService.class);
* }
* }
* install(TestingServiceModule.forServices(MyTestingService.class);
* }
* }
* </pre>
*/
public abstract class TestingServiceModule extends AbstractModule {

/** Returns a new module which will configure bindings for all the specified {@code services}. */
public static TestingServiceModule forServices(
Iterable<Class<? extends TestingService>> services) {
return new TestingServiceModule() {
@Override
protected void configureTestingServices() {
for (Class<? extends TestingService> service : services) {
bindTestingService(service);
}
}
};
}

/** Returns a new module which will configure bindings for all the specified {@code services}. */
@SafeVarargs
@CheckReturnValue
public static TestingServiceModule forServices(Class<? extends TestingService>... services) {
return forServices(ImmutableList.copyOf(services));
}

@Override
protected final void configure() {
configureTestingServices();
Expand Down
16 changes: 6 additions & 10 deletions src/test/java/com/google/acai/AcaiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package com.google.acai;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth.assertWithMessage;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -46,7 +46,6 @@ public class AcaiTest {
@Rule public ExpectedException thrown = ExpectedException.none();
@Mock private Statement statement;
@Mock private FrameworkMethod frameworkMethod;
@Mock private Service testingService;

@Before
public void cleanup() {
Expand Down Expand Up @@ -99,7 +98,7 @@ public void failingTestInjectionDoesNotAffectSubsequentTests() throws Throwable
Acai acai = new Acai(TestModule.class);
try {
acai.apply(statement, frameworkMethod, new TestWithUnsatisfiedBinding()).evaluate();
assert_().fail("Expected ConfigurationException to be thrown.");
assertWithMessage("Expected ConfigurationException to be thrown.").fail();
} catch (ConfigurationException e) {
// Expected: TestWithUnsatisfiedBinding requires binding not satisfied by TestModule.
}
Expand All @@ -114,7 +113,7 @@ public void failingBeforeTestMethodDoesNotAffectSubsequentTests() throws Throwab
Acai acai = new Acai(FailingBeforeTestModule.class);
try {
acai.apply(statement, frameworkMethod, new ExampleTest()).evaluate();
assert_().fail("Expected TestException to be thrown.");
assertWithMessage("Expected TestException to be thrown.").fail();
} catch (TestException e) {
// Expected: ServiceWithFailingBeforeTest throws TestException in @BeforeTest.
}
Expand Down Expand Up @@ -260,17 +259,15 @@ private static class DependentService implements TestingService {

@BeforeSuite
private void beforeSuite() {
assert_()
.withFailureMessage("DependentService should be run after Service")
assertWithMessage("DependentService should be run after Service")
.that(Service.methodCalls.beforeSuite())
.isEqualTo(methodCalls.beforeSuite() + 1);
methodCalls = methodCalls.incrementBeforeSuite();
}

@BeforeTest
private void beforeTest() {
assert_()
.withFailureMessage("DependentService should be run after Service")
assertWithMessage("DependentService should be run after Service")
.that(Service.methodCalls.beforeTest())
.isEqualTo(methodCalls.beforeTest() + 1);
methodCalls = methodCalls.incrementBeforeTest();
Expand All @@ -279,8 +276,7 @@ private void beforeTest() {
@AfterTest
private void afterTest() {
methodCalls = methodCalls.incrementAfterTest();
assert_()
.withFailureMessage("Service should be cleaned up after DependentService")
assertWithMessage("Service should be cleaned up after DependentService")
.that(Service.methodCalls.afterTest())
.isEqualTo(methodCalls.afterTest() - 1);
}
Expand Down
32 changes: 19 additions & 13 deletions src/test/java/com/google/acai/TestingServiceModuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.acai;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;

import com.google.inject.Guice;
import com.google.inject.Injector;
Expand All @@ -37,28 +38,33 @@ public void servicesAreBound() {
new TestingServiceModule() {
@Override
protected void configureTestingServices() {
bindTestingService(ServiceToBindByClass.class);
bindTestingService(serviceInstance);
}
});

Set<TestingService> boundServices =
injector.getInstance(new Key<Set<TestingService>>(AcaiInternal.class) {});

assertThat(boundServices).containsExactly(serviceInstance, new ServiceToBindByClass());
assertThat(boundServices).contains(serviceInstance);
}

private static class ServiceToBindByClass implements TestingService {
@Override
public boolean equals(Object obj) {
return obj.getClass() == ServiceToBindByClass.class;
}
}
@Test
public void servicesAreBoundUsingFactoryMethod() {
Injector injector =
Guice.createInjector(
TestingServiceModule.forServices(
ServiceToBindByClass.class, ServiceToBindByClassTwo.class));

Set<TestingService> boundServices =
injector.getInstance(new Key<Set<TestingService>>(AcaiInternal.class) {});

private static class ServiceToBindByInstance implements TestingService {
@Override
public boolean equals(Object obj) {
return obj == this;
}
assertThat(boundServices.stream().map(Object::getClass))
.containsExactly(ServiceToBindByClass.class, ServiceToBindByClassTwo.class);
}

private static class ServiceToBindByClass implements TestingService {}

private static class ServiceToBindByClassTwo implements TestingService {}

private static class ServiceToBindByInstance implements TestingService {}
}

0 comments on commit 7384272

Please sign in to comment.