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);
}
}