设置httpcontext中的API version进行集成测试。[已经回答了类似的问题,所以问题不适用

发布于 2025-02-11 08:18:10 字数 1715 浏览 1 评论 0原文

this < /a>问题是我需要做什么,但我没有足够的声誉来评论维克拉姆的答案。

我不能使用模拟。我们的测试已经在测试中使用了适当的HTTPContext对象。我需要的只是设置httpcontext的API version,因为我需要从ActionExecutedContext上抓取它。

编辑: 在测试文件中:

            var httpContext = new DefaultHttpContext
        {
            RequestServices = this.ServiceProviderBuilder.Build(regions).Object
        };

        QueryBuilder queryBuilder = new QueryBuilder();
        queryBuilder.Add("api-version", serviceVersion.GetDescription());
        httpContext.Request.QueryString = queryBuilder.ToQueryString();

然后将此httpcontext分配给contranterContext,该由myController使用。

我正在使用myController打电话:

                    var context = new ActionExecutedContext(
                new ActionContext
                {
                    HttpContext = myController.HttpContext,
                    RouteData = new RouteData(),
                    ActionDescriptor = new ActionDescriptor()
                },
                new List<IFilterMetadata>(),
                myController);

    IActionResult result = await myController.GetInfoAsync()

在我自己的ActionFilterAttribute中:

        /// <inheritdoc />
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // I use the requestedApiVersion later on in the code
        ApiVersion requestedApiVersion = context.HttpContext.GetRequestedApiVersion();
    }

任何帮助都将受到赞赏!

This question is what I need to do but I don't have enough reputation to comment on Vikram's answer.

I can't use Mocks. Our tests are already using a proper HttpContext object in the tests. All I need is to set the api-version of the httpcontext since I need to grab it later on from ActionExecutedContext.

EDIT:
In a test file:

            var httpContext = new DefaultHttpContext
        {
            RequestServices = this.ServiceProviderBuilder.Build(regions).Object
        };

        QueryBuilder queryBuilder = new QueryBuilder();
        queryBuilder.Add("api-version", serviceVersion.GetDescription());
        httpContext.Request.QueryString = queryBuilder.ToQueryString();

This httpContext is then assigned to ControllerContext that is used by myController.

I'm using myController to make a call:

                    var context = new ActionExecutedContext(
                new ActionContext
                {
                    HttpContext = myController.HttpContext,
                    RouteData = new RouteData(),
                    ActionDescriptor = new ActionDescriptor()
                },
                new List<IFilterMetadata>(),
                myController);

    IActionResult result = await myController.GetInfoAsync()

In my own ActionFilterAttribute:

        /// <inheritdoc />
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // I use the requestedApiVersion later on in the code
        ApiVersion requestedApiVersion = context.HttpContext.GetRequestedApiVersion();
    }

Any help is appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄荷港 2025-02-18 08:18:10

根据您的目标,可以通过多种方式实现这一目标。

按照当前编写的方式,您需要确保针对您的addapiversioning()已针对您的ServiceProviderBuilder。目前尚不清楚这是否是您设置的一部分。

您没有提及您正在使用的API版本的版本,但是即使没有任何其他注册,事情仍然可以使用。该问题可能与serviceversion.getDescription()有关。目前尚不清楚这会做什么,但它应该简单地提供API版本字符串。如果指定的值无效,则将导致httpcontext.getRequestedapiversion()扩展方法返回null

根据设计,解析失败不会导致运行时异常;但是,您可能会看到路由系统与请求的端点不匹配。在这种情况下,null是一个完全正常的返回值。

从此设置中很难看出,但是如果您需要做的就是模拟请求的,解析的API版本,则有一种简单的方法。扩展方法实际上只是获得A 功能的特定属性的快捷方式:

var feature = httpContext.Features.Get<IApiVersioningFeature>();
var rawApiVersion = feature.RawRequestedApiVersion; // unparsed
var apiVersion = feature.RequestedApiVersion;

读取特征属性。没有很多用例明确设置这些值,但是测试是其中之一。关于此功能初始化的运行时行为有所不同,但是在最新的实现中,它始终是通过扩展方法创建和设置的。可以肯定的是,您需要做的就是在测试中明确设置该功能:

IApiVersioningFeature feature = new ApiVersioningFeature(httpContext);
feature.ApiVersion = new ApiVersion(2, 0);
httpContext.Features.Set(feature);

注意:ifeatUrecollection是类型。因此,重要的是使用iapiversingfeature接口而不是混凝土类型。

在这一点上,您可以在您的内心内容中模拟或设置httpContextdefaulthttpcontext不应需要任何其他设置。如果您嘲笑httpcontext,则可能看起来像:

// arrange
var httpContext = new Mock<HttpContext>();
var features = new FeatureCollection();
IApiVersioningFeature feature = new ApiVersioningFeature(httpContext.Object);

feature.RequestedApiVersion = new ApiVersion(2, 0);
features.Set(feature);
httpContext.SetupGet(c => c.Features).Returns(features);

// act
var result = httpContext.Object.GetRequestedApiVersion();

// assert
result.Should().Be(feature.RequestedApiVersion);

There are several ways this can be achieved depending on your goals.

As is currently written, you'd need to make sure that AddApiVersioning() has been called against your ServiceProviderBuilder. It's unclear if that is part of your setup.

You didn't mention which version of API Versioning you're using, but even without any other registration, things still might have worked. The issue could be related to serviceVersion.GetDescription(). It's not clear what this does, but it should simply provide the API version string. If the specified value is invalid, this will cause the HttpContext.GetRequestedApiVersion() extension method to return null.

By design, a parsing failure doesn't cause a runtime exception; however, you would have seen the routing system not match the requested endpoint. null, in this context, is a perfectly normal return value.

It's hard to tell from this setup, but if all you need to do is simulate the requested, parsed API version, there is a much simpler way. The extension method is really just a shortcut to get a specific property of a feature:

var feature = httpContext.Features.Get<IApiVersioningFeature>();
var rawApiVersion = feature.RawRequestedApiVersion; // unparsed
var apiVersion = feature.RequestedApiVersion;

The feature properties are read/write. There aren't many use cases to explicitly set these values, but testing is one of them. The runtime behavior as to when this feature is initialized varies, but in the latest implementations, it's always created and set through the extension method. To be absolutely sure, all you need to do is setup the feature explicitly in the test:

IApiVersioningFeature feature = new ApiVersioningFeature(httpContext);
feature.ApiVersion = new ApiVersion(2, 0);
httpContext.Features.Set(feature);

Note: The key in the IFeatureCollection is the type. It is therefore important to use the IApiVersioningFeature interface and not a concrete type.

At this point, you can mock or setup the HttpContext to your heart's content. DefaultHttpContext shouldn't require any additional setup. If you were mocking HttpContext, then it might look like:

// arrange
var httpContext = new Mock<HttpContext>();
var features = new FeatureCollection();
IApiVersioningFeature feature = new ApiVersioningFeature(httpContext.Object);

feature.RequestedApiVersion = new ApiVersion(2, 0);
features.Set(feature);
httpContext.SetupGet(c => c.Features).Returns(features);

// act
var result = httpContext.Object.GetRequestedApiVersion();

// assert
result.Should().Be(feature.RequestedApiVersion);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文