mirror of
https://github.com/google/guice.git
synced 2024-04-21 12:32:36 +00:00
By setting guice_include_stack_traces flag OFF, Guice does not collect stack traces for identifying the declaring source of a binding. Instead it uses the first non-skipped module class name from the modules stack. As a result, in some cases, error messages can be slightly different with this flag. For example, the file name and line number are not always available. A sample error message with this flag : Guice creation errors: 1) Received null converting foo (bound at com.google.inject.TypeConversionTest.configure(Unknown Source) (via modules: com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest)) to java.util.Date using CustomConverter which matches only(java.util.Date) (bound at com.google.inject.TypeConversionTest.configure(Unknown Source) (via modules: com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest)). while locating java.util.Date annotated with @com.google.inject.TypeConversionTest() for field at com.google.inject.TypeConversionTest.date(TypeConversionTest.java:478) at com.google.inject.TypeConversionTest.configure(Unknown Source) (via modules: com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest) This also changes the DEFAULT flag name to ONLY_FOR_DECLARTION_SOURCE. Adds InternalFlags.getIncludeStackTraceOption() to wrap system property access. ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=53610378
252 lines
7.0 KiB
Java
252 lines
7.0 KiB
Java
package com.google.inject;
|
|
|
|
import static com.google.inject.Asserts.assertContains;
|
|
import static com.google.inject.Asserts.getDeclaringSourcePart;
|
|
|
|
import junit.framework.TestCase;
|
|
|
|
import java.lang.annotation.Documented;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.lang.annotation.Target;
|
|
|
|
/**
|
|
* @author jessewilson@google.com (Jesse Wilson)
|
|
*/
|
|
public class NullableInjectionPointTest extends TestCase {
|
|
|
|
public void testInjectNullIntoNotNullableConstructor() {
|
|
try {
|
|
createInjector().getInstance(FooConstructor.class);
|
|
fail("Injecting null should fail with an error");
|
|
}
|
|
catch (ProvisionException expected) {
|
|
assertContains(expected.getMessage(),
|
|
"null returned by binding at " + getClass().getName(),
|
|
"parameter 0 of " + FooConstructor.class.getName() + ".<init>() is not @Nullable");
|
|
}
|
|
}
|
|
|
|
public void testInjectNullIntoNotNullableMethod() {
|
|
try {
|
|
createInjector().getInstance(FooMethod.class);
|
|
fail("Injecting null should fail with an error");
|
|
}
|
|
catch (ProvisionException expected) {
|
|
assertContains(expected.getMessage(),
|
|
"null returned by binding at " + getClass().getName(),
|
|
"parameter 0 of " + FooMethod.class.getName() + ".setFoo() is not @Nullable");
|
|
}
|
|
}
|
|
|
|
public void testInjectNullIntoNotNullableField() {
|
|
try {
|
|
createInjector().getInstance(FooField.class);
|
|
fail("Injecting null should fail with an error");
|
|
}
|
|
catch (ProvisionException expected) {
|
|
assertContains(expected.getMessage(),
|
|
"null returned by binding at " + getClass().getName(),
|
|
" but " + FooField.class.getName() + ".foo is not @Nullable");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Provider.getInstance() is allowed to return null via direct calls to
|
|
* getInstance().
|
|
*/
|
|
public void testGetInstanceOfNull() {
|
|
assertNull(createInjector().getInstance(Foo.class));
|
|
}
|
|
|
|
public void testInjectNullIntoNullableConstructor() {
|
|
NullableFooConstructor nfc
|
|
= createInjector().getInstance(NullableFooConstructor.class);
|
|
assertNull(nfc.foo);
|
|
}
|
|
|
|
public void testInjectNullIntoNullableMethod() {
|
|
NullableFooMethod nfm
|
|
= createInjector().getInstance(NullableFooMethod.class);
|
|
assertNull(nfm.foo);
|
|
}
|
|
|
|
public void testInjectNullIntoNullableField() {
|
|
NullableFooField nff
|
|
= createInjector().getInstance(NullableFooField.class);
|
|
assertNull(nff.foo);
|
|
}
|
|
|
|
public void testInjectNullIntoCustomNullableConstructor() {
|
|
CustomNullableFooConstructor nfc
|
|
= createInjector().getInstance(CustomNullableFooConstructor.class);
|
|
assertNull(nfc.foo);
|
|
}
|
|
|
|
public void testInjectNullIntoCustomNullableMethod() {
|
|
CustomNullableFooMethod nfm
|
|
= createInjector().getInstance(CustomNullableFooMethod.class);
|
|
assertNull(nfm.foo);
|
|
}
|
|
|
|
public void testInjectNullIntoCustomNullableField() {
|
|
CustomNullableFooField nff
|
|
= createInjector().getInstance(CustomNullableFooField.class);
|
|
assertNull(nff.foo);
|
|
}
|
|
|
|
private Injector createInjector() {
|
|
return Guice.createInjector(
|
|
new AbstractModule() {
|
|
protected void configure() {
|
|
bind(Foo.class).toProvider(new Provider<Foo>() {
|
|
public Foo get() {
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* We haven't decided on what the desired behaviour of this test should be...
|
|
*/
|
|
public void testBindNullToInstance() {
|
|
try {
|
|
Guice.createInjector(new AbstractModule() {
|
|
protected void configure() {
|
|
bind(Foo.class).toInstance(null);
|
|
}
|
|
});
|
|
fail();
|
|
} catch (CreationException expected) {
|
|
assertContains(expected.getMessage(),
|
|
"Binding to null instances is not allowed.",
|
|
"at " + getClass().getName(), getDeclaringSourcePart(getClass()));
|
|
}
|
|
}
|
|
|
|
public void testBindNullToProvider() {
|
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
|
protected void configure() {
|
|
bind(Foo.class).toProvider(new Provider<Foo>() {
|
|
public Foo get() {
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
assertNull(injector.getInstance(NullableFooField.class).foo);
|
|
assertNull(injector.getInstance(CustomNullableFooField.class).foo);
|
|
|
|
try {
|
|
injector.getInstance(FooField.class);
|
|
}
|
|
catch(ProvisionException expected) {
|
|
assertContains(expected.getMessage(), "null returned by binding at");
|
|
}
|
|
}
|
|
|
|
public void testBindScopedNull() {
|
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
|
protected void configure() {
|
|
bind(Foo.class).toProvider(new Provider<Foo>() {
|
|
public Foo get() {
|
|
return null;
|
|
}
|
|
}).in(Scopes.SINGLETON);
|
|
}
|
|
});
|
|
assertNull(injector.getInstance(NullableFooField.class).foo);
|
|
assertNull(injector.getInstance(CustomNullableFooField.class).foo);
|
|
|
|
try {
|
|
injector.getInstance(FooField.class);
|
|
}
|
|
catch(ProvisionException expected) {
|
|
assertContains(expected.getMessage(), "null returned by binding at");
|
|
}
|
|
}
|
|
|
|
public void testBindNullAsEagerSingleton() {
|
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
|
protected void configure() {
|
|
bind(Foo.class).toProvider(new Provider<Foo>() {
|
|
public Foo get() {
|
|
return null;
|
|
}
|
|
}).asEagerSingleton();
|
|
}
|
|
});
|
|
assertNull(injector.getInstance(NullableFooField.class).foo);
|
|
assertNull(injector.getInstance(CustomNullableFooField.class).foo);
|
|
|
|
try {
|
|
injector.getInstance(FooField.class);
|
|
fail();
|
|
} catch(ProvisionException expected) {
|
|
assertContains(expected.getMessage(), "null returned by binding "
|
|
+ "at com.google.inject.NullableInjectionPointTest");
|
|
}
|
|
}
|
|
|
|
static class Foo { }
|
|
|
|
static class FooConstructor {
|
|
@Inject FooConstructor(Foo foo) { }
|
|
}
|
|
static class FooField {
|
|
@Inject Foo foo;
|
|
}
|
|
static class FooMethod {
|
|
@Inject
|
|
void setFoo(Foo foo) { }
|
|
}
|
|
|
|
static class NullableFooConstructor {
|
|
Foo foo;
|
|
@Inject NullableFooConstructor(@Nullable Foo foo) {
|
|
this.foo = foo;
|
|
}
|
|
}
|
|
static class NullableFooField {
|
|
@Inject @Nullable Foo foo;
|
|
}
|
|
static class NullableFooMethod {
|
|
Foo foo;
|
|
@Inject void setFoo(@Nullable Foo foo) {
|
|
this.foo = foo;
|
|
}
|
|
}
|
|
|
|
static class CustomNullableFooConstructor {
|
|
Foo foo;
|
|
@Inject CustomNullableFooConstructor(@Namespace.Nullable Foo foo) {
|
|
this.foo = foo;
|
|
}
|
|
}
|
|
|
|
static class CustomNullableFooField {
|
|
@Inject @Namespace.Nullable Foo foo;
|
|
}
|
|
static class CustomNullableFooMethod {
|
|
Foo foo;
|
|
@Inject void setFoo(@Namespace.Nullable Foo foo) {
|
|
this.foo = foo;
|
|
}
|
|
}
|
|
|
|
@Documented
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
|
@interface Nullable { }
|
|
|
|
static interface Namespace {
|
|
@Documented
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
|
@interface Nullable { }
|
|
}
|
|
}
|