MyTested.AspNetCore.Mvc icon indicating copy to clipboard operation
MyTested.AspNetCore.Mvc copied to clipboard

Add a value provider within `From`

Open jayharris opened this issue 3 years ago • 2 comments

Is your feature request related to a problem? Please describe. I am trying to test using aborted cancellation tokens to check request abort logic within a filter. However, there is no way to do so. A CancellationToken on MyMvc.Pipeline() must be explicitly set as CancellationToken.None or default(CancellationToken). If I use an aborted token, such as new CancellationToken(true), then the route value logic will fail as no matching RouteValue token because new CancellationToken(true) doesn't match default(CancellationToken). There does not seem to be any way to ignore an Action's method argument outside of using the With and From classes.

Describe the solution you'd like It would be helpful to be able to provide a non-default value while still having that route key ignored. Perhaps it would be simplest to add another method to the From class, similar to From.Services<>, that returns a value (or a value from an expression). Because anything coming through the From static class gets a value but is ignored via ExpressionParser, the Action will still get the resolved value, but the value will not be checked against RouteData.

public static class From
{
  /* Omitted */
  public static TValue Value<TValue>(TValue value) => value;
}

Use:

MyMvc.Pipeline()
.ShouldMap(request => request.WithLocation("/system/dosomething"))
.To<SystemController>(controller => controller.DoSomething( From.Value(new CancellationToken(true) ))

Additional context I would be happy to provide a PR if it would be helpful.

Or maybe I'm just missing something.

jayharris avatar Jan 01 '21 01:01 jayharris

I added two new methods on the With class - Value and IgnoredRouteValue. They will be available from version 5.0. Both methods do the same thing - they ignore the value during the route assertion but use it during action execution. You can choose whichever method feels more "readable" to you. Here is an example:

MyPipeline
    .Configuration()
    .ShouldMap("/Home/CancelledTask/1")
    .To<HomeController>(c => c.CancelledTask(1, With.IgnoredRouteValue(new CancellationToken(true))))
    .Which()
    .ShouldReturn()
    .Ok();

ivaylokenov avatar Jul 12 '21 08:07 ivaylokenov

This works great. Thank you.

jayharris avatar Apr 20 '22 21:04 jayharris