I am currently implementing unit tests in a ASP.NET Core project and I have to test the POST method of an API Controller. Here is an example of the POST method:
[HttpPost]
public IActionResult Post([FromBody]Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest();
    }
    try
    {
        var returnValue = productService.Save(product);
        return CreatedAtRoute(nameof(Post), new { returnValue = returnValue }, product);
    }
    catch
    {
        return BadRequest();
    }
}
And here is an example of the model I am using:
public class Product
{
    [Required]
    [MaxLength(25)]
    public string Name { get; set; }
    [MaxLength(200)]
    public string Description { get; set; }
}
The main idea is to test both Created (201) and also Bad Request (400) results. I went through this page and the Created (201) works pretty fine. However, when I applied the same logic for the Bad Request (401) it didn't work since I am not making a real request. But when I tried using PostMan with the "wrong" values I got 400, as expected.
How can I simulate a POST request from a unit test? Or am I missing something?
The documentation you went through is for classic ASP.NET. Look at ASP.NET Core docs instead: Integration testing.
There is the TestServer class designed for controller testing in ASP.NET Core:
_server = new TestServer(new WebHostBuilder()
    .UseStartup<Startup>());
_client = _server.CreateClient();
var content = new StringContent($"username={_username}&password={_password}",
    Encoding.UTF8,
    "application/x-www-form-urlencoded");
HttpResponseMessage response = await _client.PostAsync("foo_path", content);
Remarks:
TestServer is parametrized by Startup class. Probably you would create a separate Startup class for testing or override its methods in some way to mock dependencies.
An in-memory server instance is accessible only from a client created by _server.CreateClient() call.  The client is created with a special HttpMessageHandler inside. That handler allows to directly call APIs under test without exposing the in-memory instance as a real HTTP server.
Another option might be used for integration testing is to run a "real" Kestrel server to test your web API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With