tmenier / Flurl

Fluent URL builder and testable HTTP client for .NET
https://flurl.dev
MIT License
4.23k stars 387 forks source link

Empty request body when testing Multipart request #750

Closed MahmoudH96 closed 1 year ago

MahmoudH96 commented 1 year ago

I'm trying to write a unit test for a service that calls an endpoint and sends a multipart form.

My service code

public class DummyService
    {
        public IFlurlClient FlurlClient { get; set; }
        public DummyService(IFlurlClient flurlClient)
        {
            FlurlClient = flurlClient;

        }

        public async Task CallMultipartApi()
        {
            var response = await FlurlClient.Request("https://localhost:8080/dummy")
                .PostMultipartAsync(mp =>
                {
                    mp.AddString("client_id", "test");
                    mp.AddString("client_secret", "test");
                });
        }
    }

And my unit test code

 public class DummyServiceTest
    {
        [Fact()]
        public async void TestCallMultipartApi()
        {
            using (var httpTest = new HttpTest())
            {

                httpTest
                    .ForCallsTo("*")
                    .WithVerb(HttpMethod.Post.ToString())
                    .WithHeader("Content-Type", "application/x-www-form-urlencoded")
                    .RespondWith(status: 200);

                var service = new DummyService(new FlurlClient());
                await service.CallMultipartApi();

                Assert.NotEmpty(httpTest.CallLog.First().RequestBody);
            }

        }
    }

Nevertheless my test is failing as I cannot get any Request body out of the CallLogs, I also looked at your documentation code for the Testable http and there aren't any examples regarding testing Multipart forms.

tmenier commented 1 year ago

Your call log is empty because you're filtering on Content-Type application/x-www-form-urlencoded. The Content-Type for multipart requests is multipart/form-data, likely with a random boundary as well. Use WithContentType("multipart/form-data"), which is forgiving enough to ignore any boundary added.