UnsatisfiedDependencyException: Il n'y a pas d'objet disponible pour l'injection au SystemInjecteeImpl
Il y a des erreurs lors de l'utilisation de DI en Maillot Reste d'application:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=PricingService,parent=PricingResource,qualifiers={},position=0,optional=false,self=false,unqualified=null,1633188703)
Je suis assez nouveau dans le concept, et il semble assez compliqué, car il y a quelques exemples qui semble être obsolète. Comme je comprends qu'il ya quelques façons de le faire (DI): natif HK2, Printemps/HK2 Pont. Ce qui est plus facile et plus simple à configurer? Comment configurer par programmation (pas un fan de XML) pour le Jersey 2.x?
ResourceConfig
import org.glassfish.jersey.server.ResourceConfig;
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
register(new ApplicationBinder());
packages(true, "api");
}
}
AbstractBinder
public class ApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(PricingService.class).to(PricingService.class).in(Singleton.class);
}
}
PricingResource
@Path("/prices")
public class PricingResource {
private final PricingService pricingService;
@Inject
public PricingResource(PricingService pricingService) {
this.pricingService = pricingService;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Collection<Price> findPrices() {
return pricingService.findPrices();
}
}
PricingService
@Singleton
public class PricingService {
//no constructors...
//findPrices() ...
}
Mise à JOUR
public class Main {
public static final String BASE_URI = "http://localhost:8080/api/";
public static HttpServer startServer() {
return createHttpServerWith(new ResourceConfig().packages("api").register(JacksonFeature.class));
}
private static HttpServer createHttpServerWith(ResourceConfig rc) {
HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
StaticHttpHandler staticHttpHandler = new StaticHttpHandler("src/main/webapp");
staticHttpHandler.setFileCacheEnabled(false);
staticHttpHandler.start();
httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler);
return httpServer;
}
public static void main(String[] args) throws IOException {
System.setProperty("java.util.logging.config.file", "src/main/resources/logging.properties");
final HttpServer server = startServer();
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
server.start();
System.in.read();
server.stop();
}
}
UPDATE3:
public class PricingResourceTest extends JerseyTest {
@Mock
private PricingService pricingServiceMock;
@Override
protected Application configure() {
MockitoAnnotations.initMocks(this);
enable(TestProperties.LOG_TRAFFIC);
enable(TestProperties.DUMP_ENTITY);
ResourceConfig config = new ResourceConfig(PricingResource.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(pricingServiceMock).to(PricingService.class);
}
});
return config;
}
@Test
public void testFindPrices(){
when(pricingServiceMock.findPrices()).thenReturn(getMockedPrices());
Response response = target("/prices")
.request()
.get();
verify(pricingServiceMock).findPrices();
List<Price> prices = response.readEntity(new GenericType<List<Price>>(){});
// assertEquals("Should return status 200", 200, response.getStatus());
assertTrue(prices.get(0).getId() == getMockedPrices().get(0).getId());
}
private List<Price> getMockedPrices(){
List<Price> mockedPrices = Arrays.asList(new Price(1L, 12.0, 50.12, 12L));
return mockedPrices;
}
}
JUnit sortie:
INFO: 1 * Client response received on thread main
1 < 200
1 < Content-Length: 4
1 < Content-Type: application/json
[{}]
java.lang.AssertionError
En cours de débogage:
prices.get(0)
est Price
objet qui a null
attribué à tous les domaines.
UPDATE4:
Ajouté à configure()
:
config.register(JacksonFeature.class);
config.register(JacksonJsonProvider.class);
Maintenant Junit sortie un peu mieux:
INFO: 1 * Client response received on thread main
1 < 200
1 < Content-Length: 149
1 < Content-Type: application/json
[{"id":2,"recurringPrice":122.0,"oneTimePrice":6550.12,"recurringCount":2},{"id":2,"recurringPrice":122.0,"oneTimePrice":6550.12,"recurringCount":2}]
En effet liste prices
a bon nombre de prices
mais tous les prix des " champs est null. Qui conduit à l'hypothèse que le problème est peut-être la lecture de l'entité:
List<Price> prices = response.readEntity(new GenericType<List<Price>>(){});
Ici est de savoir comment fixer
Changement Moxy dépendance:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
et d'ajouter des annotations sur les "Prix" de l'objet.
@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
Vous n'êtes pas vous même à l'aide de la
ResourceConfig
dans votre post. Vous créez un nom complètement différent createHttpServerWith(new ResourceConfig()..
ResourceConfig est défini dans
Main
et ApplicationConfig
mais il semble que ces deux ne sont pas likned ensemble.....peut-êtrePourquoi seraient-ils liés? Utilisez simplement
createHttpServerWith(new ApplicationConfig())
La principale chose que vous êtes absent de la maquette de l'initialisation des données. Vous ne devez le faire à l'intérieur de votre méthode d'essai. Comme vous l'avez fait dans votre question précédente, qui est aujourd'hui disparu, dans cette question,
OriginalL'auteur J.Olufsen | 2016-04-27
Vous devez vous connecter pour publier un commentaire.
Oublier le
InjectableProvider
. Vous n'en avez pas besoin. Le problème est que le se moquer de service n'est pas un être injecté. Il est celui qui a été créé par le DI-cadre. Si vous êtes à la vérification de changements sur la maquette de service, qui n'a jamais été touché.Donc ce que vous devez faire est de lier la maquette avec le DI-cadre. Vous pouvez simplement créer un autre
AbstractBinder
pour les tests. Il peut être un simple anonyme, où vous pourrez vous lier la maquetteIci vous êtes tout simplement la liaison de la moqué de service. Donc le cadre qui permettra d'injecter de la maquette dans la ressource. Maintenant, quand vous la modifier dans la demande, les modifications seront vus dans l'affirmation
Oh, et vous devez toujours faire de votre
when(..).then(..)
pour initialiser les données dans le simulacre de service. C'est aussi ce qui vous manqueassertTrue(prices.get(0).getId() == getMockedPrices().get(0).getId());
Avez-vous initialiser la simulation de données avec
when(..).thenXxx(..)
?Je pense que oui,mon test est affiché en
UPDATE3
avez-vous fait tout de débogage? Comme la vérification de la liste à l'intérieur de la méthode. Les données dans la liste? Si c'est le cas, il semble y avoir un problème avec la sérialisation
Vous n'êtes pas obtenir ce que je veux dire. Le méthode est la méthode avec
@GET
sur le côté serveur. Vérifier la liste retournée par l'appel du service de l'intérieur de la méthode. Vous pouvez ajouter un simple S. O. P si vous le souhaitez. Si le prix est dans la liste après retriving de service, alors cela signifie que le serveur a un problème de sérialisation de la réponseOriginalL'auteur Paul Samsotha
J'ai résolu ce problème en ajoutant la dépendance suivant ma demande.
compiler groupe: 'org.glassfish.jersey.les conteneurs.glassfish', nom: 'jersey-gf-cdi', version: '2.14'
Il n'est pas nécessaire d'avoir tout "AbstractBinder" le code associé.
!Jersey et point de Terminaison de la classe(point d'injection) !
OriginalL'auteur nrkkalyan