Flurl fails to validate request json

39 views Asked by At

I have a Flurl project and one unit test that is failing and I can't figure out why. Here is my test:

    [Fact]
    public async Task SaveReport_Test()
    {
        using (var httpTest = new HttpTest())
        {
            //Arrange
            var report =
                new UsageReportDto("fake program id", new Version(3, 2), "fake license", "fake scope", "Revit 2019",
                                12345)
                {
                    Is64                = true,
                    OsVersion           = new Version(10, 4),
                    OsVersionString     = "fake os string",
                    ProgramClose        = DateTime.Now,
                    ProgramOpen         = DateTime.Now,
                    RevitNumericVersion = 2019,
                    UserId              = "fake user"
                };
            report.EnabledFeatures.AddRange(new List<string>() {"fake", "features"});
            report.Files.AddRange(new List<FileReportDataDto>()
                {new FileReportDataDto(Guid.NewGuid()) {IsClosed = false}});

            httpTest.RespondWith(status: (int)HttpStatusCode.NoContent)
                .RespondWith(status: (int)HttpStatusCode.Unauthorized);
            ApiUnauthenticatedException exUnauthorized = null;
            ApiTimeoutException exTimeout = null;

            //Act
            await _service.SaveReportAsync(report);

            try
            {
                await _service.SaveReportAsync(report);
            }
            catch (ApiUnauthenticatedException ex)
            {
                exUnauthorized = ex;
            }
            try
            {
                httpTest.SimulateTimeout();
                await _service.SaveReportAsync(report);
            }
            catch (ApiTimeoutException ex)
            {
                exTimeout = ex;
            }

            //Assert
            Assert.NotNull(TestData.AuthService.CurrentAuth);

            httpTest.ShouldHaveCalled(Url.Combine(UsageReportService.UsageReportBaseUrl))
                .WithHeader("user-agent", ApiData.UserAgent)
                .WithVerb(HttpMethod.Post)
                .WithRequestJson(report)
                .WithOAuthBearerToken(TestData.AuthService.CurrentAuth.AccessToken)
                .Times(3);

            Assert.NotNull(exUnauthorized);
            Assert.NotNull(exTimeout);
        }
    }

As you can see, I basically create an object and try to save it 3 times with different responses in Flurl. I use this pattern elsewhere too and it seems to work fine so I'm not sure why it's failing here.

I have figured out that I can take out the line .WithRequestJson(report) and it passes so it's something about that validation that is tripping it up. The object doesn't change at all so I don't know what would be different about it. I have looked at the object itself as well as the different calls that were made and I can't find any difference in the objects.

It also says it was expecting 3 calls but only one was made, so apparently one was made correctly but 2 were not matching that object. That doesn't make sense though because there is nothing that would modify the object.

Just for completeness, here is the SaveReportAsync function; as you can see it never modifies the object, just posts it as JSON:

    public async Task SaveReportAsync(UsageReportDto report)
    {
        if (report == null) throw new ArgumentNullException(nameof(report));
        await _authService.ValidateAccessTokenAsync().ConfigureAwait(false);
        if (string.IsNullOrEmpty(_authService.CurrentAuth?.AccessToken))
            throw new ApiUnauthenticatedException("No valid access token was found");

        try
        {
            await Url.Combine(UsageReportBaseUrl)
                     .WithHeader("user-agent", ApiData.UserAgent)
                     .WithOAuthBearerToken(_authService.CurrentAuth.AccessToken)
                     .PostJsonAsync(report)
                     .ConfigureAwait(false);
        }
        catch (FlurlHttpException ex)
        {
            throw await FlurlErrorHandler.GetFinalException(ex, string.Empty).ConfigureAwait(false);
        }
    }
0

There are 0 answers