2

I have an isolated Azure Function that makes couple of HTTP POST calls. I am trying to write an integration test for them. But the test setup fails with a gRPC error.

Here is the Program.cs that configures the HttpClient with services.AddHttpClient();

public class Program
{

    public static void Main()
    {
        var host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .ConfigureServices(services =>
            {
                services.AddHttpClient();
            }).Build();

        host.Run();
    }
}

The sample function looks like this:

public class AzFunctionEndpoint
{        
    public AzFunctionEndpoint(IHttpClientFactory httpClientFactory, IConfiguration configuration, ILoggerFactory loggerFactory)
    {
        logger = loggerFactory.CreateLogger<ResolveEndpoint>();
        this.httpClientFactory = httpClientFactory;
        this.configuration = configuration;
    }

    [Function("azfunction")]
    public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = "azs/azfunction")] HttpRequestData req)
    {
        
        // Couple of other HTTP calls using httpClientFactory
        
        // return
        var res = req.CreateResponse(HttpStatusCode.OK);
        return res;
        
    }        

    private readonly IConfiguration configuration;
    private readonly IHttpClientFactory httpClientFactory;
    private readonly ILogger logger;
}

The Function runs correctly on local machine and when deployed to Azure.

Now I try and create an integration test with

public class AzFunctionEndpointIntegrationTests
{
    public AzFunctionEndpointIntegrationTests()
    {
        factory = new WebApplicationFactory<Program>();
        var clientFactory = factory.Services.GetService<IHttpClientFactory>();

        // THIS LINE CAUSES gRPC host error 
        client = clientFactory.CreateClient();
    }

    [Fact]
    public async Task AzFunction_Should_BeOK()
    {
        // POST to the azure function
        HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(HttpMethods.Post), "api/azs/azfunction");

        var response = await client.SendAsync(request);

        response.StatusCode.Should().Be(System.Net.HttpStatusCode.OK);
    }

    private HttpClient client;
    private WebApplicationFactory<Program> factory;
}

The test code that tries to create HttpClient to invoke my function causes this exception

client = clientFactory.CreateClient();

System.InvalidOperationException : The gRPC channel URI 'http://:51828' could not be parsed.

I don't quite understand what is this error ! Any help on writing integration tests for Azure Functions is appreciated.

ameya
  • 1,448
  • 1
  • 15
  • 31

1 Answers1

0

System.InvalidOperationException : The gRPC channel URI 'http://:51828' could not be parsed.

I don't quite understand what is this error ! Any help on writing integration tests for Azure Functions is appreciated.

Below are the few workaround may help to fix the above issue.

  • Based on this GitHub issue the root cause we have observed that, May be due to the usage of incorrect run/debug configuration the IDE you are using.

Please make sure that you are using the same as suggested on the given gitHub link to run the application.

To write an Integration test you can refer this Example for your function app.

Example of sample code:-

test.cs

[TestClass]
public class DefaultHttpTriggerTests
{
    private HttpClient _http;

    [TestInitialize]
    public void Initialize()
    {
        this._http = new HttpClient();
    }

    [TestCleanup]
    public void Cleanup()
    {
        this._http.Dispose();
    }

    [TestMethod]
    public async Task Given_OpenApiUrl_When_Endpoint_Invoked_Then_It_Should_Return_Title()
    {
        // Arrange
        var requestUri = "http://localhost:7071/api/openapi/v3.json";

        // Act
        var response = await this._http.GetStringAsync(requestUri).ConfigureAwait(false);
        var doc = JsonConvert.DeserializeObject<OpenApiDocument>(response);

        // Assert
        doc.Should().NotBeNull();
        doc.Info.Title.Should().Be("OpenAPI Document on Azure Functions");
        doc.Components.Schemas.Should().ContainKey("greeting");

        var schema = doc.Components.Schemas["greeting"];
        schema.Type.Should().Be("object");
        schema.Properties.Should().ContainKey("message");

        var property = schema.Properties["message"];
        property.Type.Should().Be("string");
    }
}

For more information please refer the below links:-

SO THREAD:- System.InvaliOperationException: The gRPC channel URI 'http://0' could not be parsed .

MICROSOFT DOCUMENTATION:- Guide for running C# Azure Functions in an isolated process

AjayKumarGhose
  • 4,257
  • 2
  • 4
  • 15