08 - Testing and Local Debugging (Flex Consumption)¶
Unit-test your Java function methods with JUnit 5, mock HttpRequestMessage and ExecutionContext with Mockito, run integration tests against Azurite, and attach a remote debugger to the running host.
Prerequisites¶
| Tool | Minimum version | Purpose |
|---|---|---|
| Java | 17 | Run function code and tests |
| Maven | 3.9 | Build and test runner |
| Azure Functions Core Tools | 4.x | Local host and debugging |
| JUnit 5 + Mockito | Latest | Test frameworks |
| Azurite | 3.x | Local Azure Storage emulator |
What You'll Build¶
You will add JUnit 5 tests to the Flex Consumption app that unit-test an HTTP function, mock the request and execution context, run an Azurite integration test, and attach IntelliJ or VS Code to a debug-enabled host.
1. Unit Test the Function Method¶
Keep logic in a plain method so it is testable without Azure types.
// src/main/java/com/example/Greeter.java
public final class Greeter {
public static String build(String name) {
String value = (name == null || name.isBlank()) ? "world" : name.trim();
return "Hello, " + value + "!";
}
}
// src/test/java/com/example/GreeterTest.java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class GreeterTest {
@Test
void buildsGreeting() {
assertEquals("Hello, ada!", Greeter.build(" ada "));
}
}
2. Mock the Trigger with Mockito¶
Mock HttpRequestMessage, ExecutionContext, and the response builder to test the trigger method end to end.
// src/test/java/com/example/HttpFunctionTest.java
import com.microsoft.azure.functions.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.*;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
class HttpFunctionTest {
@Test
void returnsGreeting() {
@SuppressWarnings("unchecked")
HttpRequestMessage<Optional<String>> req = mock(HttpRequestMessage.class);
when(req.getQueryParameters()).thenReturn(Map.of("name", "grace"));
final HttpResponseMessage.Builder builder = mock(HttpResponseMessage.Builder.class);
when(req.createResponseBuilder(any(HttpStatus.class))).thenReturn(builder);
when(builder.body(any())).thenReturn(builder);
when(builder.build()).thenReturn(mock(HttpResponseMessage.class));
ExecutionContext ctx = mock(ExecutionContext.class);
when(ctx.getLogger()).thenReturn(java.util.logging.Logger.getGlobal());
new HttpFunction().run(req, ctx);
verify(req).createResponseBuilder(HttpStatus.OK);
}
}
3. Integration Test Against Azurite¶
Use the well-known development connection string (UseDevelopmentStorage=true) with the Azure Storage Queue SDK to create, send, and read a message inside a JUnit test, then delete the queue. This validates binding behavior without a real storage account.
4. Remote Debugging with Core Tools¶
Start the host with JVM debug options and attach on port 5005.
mvn azure-functions:run -DenableDebug
# or export JAVA_OPTS before func start:
export JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
func start
Attach a Remote JVM Debug run configuration to localhost:5005 in IntelliJ, set a breakpoint in the function method, then invoke http://localhost:7071/api/hello?name=ada.
Flex Consumption note
Testing and debugging run entirely on your local machine and are identical across hosting plans. The Flex Consumption plan changes only how the deployed app scales and networks.
Verification¶
- [ ]
mvn testreports all tests passing. - [ ] The Azurite integration test round-trips a queue message without a real storage account.
- [ ] A breakpoint in the function method is hit when you invoke the local endpoint over the JDWP attach.
Next Steps¶
- Wire
mvn testinto your pipeline — see 06 - CI/CD. - Extend coverage to the triggers you added in 07 - Extending with Triggers.
See Also¶
- Testing recipe — Framework-agnostic testing patterns
- Run functions locally — Core Tools reference
- 07 - Extending with Triggers