I'm getting a rather unhelpful NullPointerException from my junit test of my Azure Functions test service with SpringCloud. I am a complete novice at this, so I apologize if this seems obvious.
The stack trace:
java.lang.NullPointerException
at org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler.doResolveName(AzureSpringBootRequestHandler.java:86)
at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.initFunctionConsumerOrSupplierFromCatalog(AbstractSpringFunctionAdapterInitializer.java:387)
at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.initialize(AbstractSpringFunctionAdapterInitializer.java:124)
at org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler.handleRequest(AzureSpringBootRequestHandler.java:58)
at test.TestCloud.start(TestCloud.java:42)
I thought maybe that the NPE was caused by me passing null into the 2nd parameter of handleRequest, but this is what the example I looked at was doing. I've tried with both the commented line or the line below it, using the concrete extension I made or the generic version. Both behaved the same, and control never gets to the execute method. The example uses the generic class, but the specific implementation seemed to make more sense to me (otherwise I don't see how the connection gets made).
@Test
public void start() throws Exception {
// AzureSpringBootRequestHandler<String, String> handler = new AzureSpringBootRequestHandler<String, String>(CloudFunctionApplication.class);
AzureReverseAdapter handler = new AzureReverseAdapter(CloudFunctionApplication.class);
String result = handler.handleRequest("Hello World", null);
handler.close();
Assert.assertEquals(result, "dlroW olleH");
}
The test class has just one function in it right now, and it is below.
@FunctionName("reverseString")
public String execute(@HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request, ExecutionContext context) {
context.getLogger().info("Input: " + request.getBody().get());
return handleRequest(request.getBody().get(), context);
}
The CloudFunctionApplication class has a method that look like below. Oddly, and I don't know how, but control DOES get to this function. I thought the execute method was supposed to act as a redirect but it seems to find reserveString anyway. I guess because it is the only @FunctionName?
This is the method. The breakpoint on the return(value) -> { line get hit by the breakpoint, but then the exception happens before the internal gets called.
@Bean
public Function<String, String> reverseString() {
return (value) -> {
return new StringBuilder(value).reverse().toString();
};
}
UPDATE: The linked question absolutely is NOT a duplicate of this question. Yes, all NullPointerExceptions are because something was null when you tried to dereference it. That link was a generic treatment of that. This was a specific question about why I was getting that from a 3rd party library. So they are absolutely NOT the same.
However, I have found the issue as suggested in the comments. It was that I was passing null in as the 2nd parameter. This seemed allowed because of the example I was working on which did the same. My solution was to mock fabricate an ExecutionContext object that returned basic values. Unfortunately, I can't record that as the answer because someone thinks I was just asking what a NullPointerException was and marked the question as a dupe.
So for anyone else who hits the same issue, that was my answer.