tanmayghosh2507
tanmayghosh2507

Reputation: 773

c# xUnit Moq It.IsAny<object> not mocking as expected

Following is the piece of code(simple HTTP post call), I am trying to mock in Azure Function:

await httpClient.PostAsync("https://url.com", await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json"));

Note that the httpClient.PostAsync() function takes two arguments: URL as string and body as object.

Now, in my test, I am mocking this POST call like this:

httpClientMock.Setup(s => s.PostAsync(It.IsAny<string>(), It.IsAny<object>())).ReturnsAsync(mockedHttpResponse);

I was expecting that await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json") would not be called as I set it to work with any object. However, my test case fails with this exception:

Found System.ArgumentNullException with message "Value cannot be null. (Parameter 'path1')" at System.IO.Path.Combine(String path1, String path2)

When I provide the correct path(even a dummy path doesn't work) by setting up the Environment variable in Test, it works. But that doesn't seem the correct way, as the unit tests are intended to run in various machines and the base path will be different for each one of them.

Upvotes: 0

Views: 1433

Answers (2)

Richiban
Richiban

Reputation: 5930

The answer is that you haven't actually intercepted the call to File.ReadAllTextAsync(...);

Remember that

await httpClient.PostAsync("https://url.com", 
    await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json"));

is functionally the same as:

var fileContent = await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json");

await httpClient.PostAsync("https://url.com", fileContent);

This way it's more obvious that, even if you mock httpClient.PostAsync, the call to File.ReadAllTextAsync still happens.

Upvotes: 0

DSN
DSN

Reputation: 397

File.ReadAllTextAsync() returns a string, so your MOQ setup should have It.IsAny<string>() as the second param instead of It.IsAny<object>().

Upvotes: 0

Related Questions