When developing any feature, it's important to test your code locally to ensure everything works as expected. This is no different when you're working with Azure Functions. Running and testing them locally is crucial. As you begin working with Azure Functions, you might find yourself excited about this powerful technology. However, even small configuration mistakes, especially for local execution, can lead to issues. Regardless of whether you're using Visual Studio, Rider, or another IDE, if your work environment or project isn't properly set up, you might encounter some challenges.
This article will guide you in preparing your local environment to run Azure Functions, help you create a fully configured new project, or ensure that your existing project is ready for local execution. While I will be using Rider as my main IDE in this article, feel free to use the IDE of your choice. The final steps where we actually run the Azure Function might differ slightly, but they should be quite similar across different IDEs.
Required components for local testing:
-
The latest version of Azurite.
According to Microsoft's docs, the Azure storage emulator can no longer be used for local testing of Azure Functions.
How to install/update the latest version of Azurite
Azurite is a part of Visual Studio, so you need to install or update Visual Studio entirely to the latest version via Visual Studio Installer. Strongly recommend restarting your PC after installation/updating.
Rider doesn't have pre-installed Azurite, but its exe file is mandatory to run Azure Functions locally. -
The 'Azure Toolkit for Rider' plugin.
How to install the ‘Azure Toolkit for Rider’ plugin.
- Open Rider;
- Open Settings (File → Settings or Ctrl + Alt + S);
- Go to the ‘Plugins’ setting block;
- Search ‘Azure Toolkit for Rider’ or use this link Azure Toolkit for Rider - IntelliJ IDEs Plugin | Marketplace ;
- Install the plugin;
-
Configured Azurite paths on Rider.
How to configure Azurite paths to use it in Rider
- Open Rider;
- Open Settings (File → Settings or Ctrl + Alt + S);
- Go to the 'Tools' setting block
- Go to ‘Azure’
- Go to ‘Azurite’
- Enter ‘Azurite executable path’ (Check path here: Use Azurite emulator for local Azure Storage development)
- Make sure that ‘Azurite workspace’ is set as ‘Managed by Rider’
Prepare local.settings.json
Make sure that the Values block contains the following values:
-
FUNCTIONS_WORKER_RUNTIME = "dotnet" / "dotnet-isolated” if you use the isolated paradigm in your Azure Functions.
Details -
FUNCTIONS_WORKER_RUNTIME_VERSION = "~8" It is a current version of .Net we’re using, so we can use .Net 8 until November 10, 2026.
Details -
FUNCTIONS_INPROC_NET8_ENABLED = "1" It is required because if it is nonexistent the error might happen (but might not happen, love magic 🪄) when we try to run Azure Functions on .Net 8 locally.
Details -
AzureWebJobsStorage = "UseDevelopmentStorage=true"
Details
Locally Running
- As an example, let’s create a new Azure Functions project via Rider. You can choose any of the Function runtime, but I will use Default worker for further demonstration.
- Create a new HTTP Azure Function Trigger because it is the easiest to trigger.
-
On the right from the line numbers, you can see a button to run a specific Azure Function.
public static class TestFunctions { [FunctionName("TestFunctions")] public static async Task
RunAsync( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); string name = req.Query["name"]; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); name = name ?? data?.name; string responseMessage = string.IsNullOrEmpty(name) ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response." : $"Hello, {name}. This HTTP triggered function executed successfully."; var okObjectResult = new OkObjectResult(responseMessage); return okObjectResult; } } -
Click on Trigger 'TestFunctions'...
-
On the opened window we can trigger our Azure Function locally later, but one important thing.
By default, the URL to trigger Azure Function looks like this GET http://localhost:7071/api/TestFunctions
Make sure whether your project reset default to any custom one. -
To run Azure Function, click on this button and click on Debug 'TestFunctions'...
If all messages are green and there is no red log message, it’s a good sign and likely you can trigger Azure Functions. -
Go back to the window where we can trigger Azure Function, change port to 7016 and click on Run.
GET http://localhost:7016/api/TestFunctions
-
After that, a window with the request result will be opened.
Conclusion
If you've followed everything correctly, congratulations! You can now run Azure Functions locally and test them before deploying to production. Testing plays a crucial role in ensuring that new changes don't adversely affect the existing functionality of your system, helping to prevent unwanted bugs and customer conflicts. Looking ahead, this foundational skill allows you to continuously refine and adapt your Azure Functions setup to meet evolving requirements and future needs, ensuring your applications remain robust and versatile.
Furthermore, by modifying the code of the TestFunctions class used in this article, you can expand its capabilities to suit various scenarios. Whether you're processing file uploads, managing real-time data processing, making inferences with data models, running scheduled tasks, building a scalable web API, responding to database changes, or creating reliable messaging systems, Azure Functions offers many possibilities.
For a deeper dive into the variety of ways you can use Azure Functions, be sure to explore the official Microsoft documentation here.