asp.net-web-api - 使用 xUnit 和 .Net Core MVC Controller 为 CORS 创建单元测试

标签 asp.net-web-api .net-core cors dotnet-httpclient xunit.net

我想编写一个单元测试以确保 CORS 处于打开状态,并且只能从报告来自特定域的客户端调用特定的 WebApi 方法。

我想我遇到了此处描述的常见陷阱,因此它不被视为真正的跨域请求...

CORS Gotchas

单元测试的类型看起来像这样......

    [Fact]
    public async Task CheckCors()
    {
        var httpClient = new HttpClient();
        httpClient.BaseAddress = new Uri("http://clientdomain.co.uk/");
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var response = await client.GetAsync(new Uri($"http://apidomain.co.uk/api/testcors", UriKind.Absolute));

        // Should be forbidden to call the api
        response.StatusCode.Should().Be(HttpStatusCode.Forbidden);
    }

我可能误解了一些事情,但谁能纠正我的错误?

最佳答案

首先,这不是单元测试,因为您正在调用某些外部资源。单元测试应该模拟/伪造任何外部依赖项。这实际上是一个集成测试。

此外,这并不是真正测试您的代码来配置 cors,而是测试 cors 是否确实有效。

话虽如此,我尝试为 CORS 编写单元测试并想出了这个。鉴于我有配置 CORS 的类

public static class CorsConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute(ConfigurationManager.AppSettings["CorsClientUrl"], "*", "*")
        {
            SupportsCredentials = true
        };

        config.EnableCors(cors);
    }
}

我的 AppSettings["CorsClientUrl"] 的值为“https://www.google.com

那么我想测试调用后是否配置了 cors。我所有的单元测试都派生自 SpecificationBase,这样我在编写测试时就有了更多 BDD 风格的语法

[TestFixture]
public abstract class SpecificationBase
{
    [SetUp]
    public void SetUp()
    {
        Given();
        When();
    }

    protected virtual void Given()
    {
    }

    protected virtual void When()
    {
    }
}

public class ThenAttribute : TestAttribute
{
}

最终的单元测试是这样的

    public class WhenConfiguringCors : SpecificationBase
    {
        private HttpConfiguration _httpConfiguration;
        private CorsPolicy _corsPolicy;

        protected override void Given()
        {
            _httpConfiguration = new HttpConfiguration();
        }

        protected override void When()
        {
            CorsConfig.Register(_httpConfiguration);

            var corsConfig = _httpConfiguration.Properties["MS_CorsPolicyProviderFactoryKey"] as AttributeBasedPolicyProviderFactory;

            _corsPolicy =
                corsConfig.DefaultPolicyProvider.GetCorsPolicyAsync(new HttpRequestMessage(), CancellationToken.None)
                    .Result;
        }

        [Then]
        public void ShouldSetOrigin()
        {
            Assert.That(
                _corsPolicy.Origins.Contains("https://www.google.com"), Is.True);
        }

        [Then]
        public void ShouldSupportCredentials()
        {
            Assert.That(
                _corsPolicy.SupportsCredentials, Is.True);
        }
    }

关于asp.net-web-api - 使用 xUnit 和 .Net Core MVC Controller 为 CORS 创建单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52448785/

相关文章:

asp.net-mvc - 如何为我的 Web API Web 服务实现身份验证和授权?

.net-core - 持续部署环境中的 dotnet 语义版本控制

angular - 对源地址 'http://localhost:4200' 处的 XMLHttpRequest 的访问已被 CORS 策略阻止

c# - 在 ApiController 上执行 POST 时处理发送的 id 的最佳实践?

OData 服务版本控制

.net - 什么时候可以提供对 Dotnet Core 的 Oracle 数据库支持?

c# - 命名空间 'AzureAD' 中不存在类型或命名空间名称 'Microsoft.AspNetCore.Authentication'

node.js - 在服务器端使用 cors 从 axios 响应中获取 Cookie

google-app-engine - XMLHttpRequest 错误

asp.net-mvc - 如何将日志记录添加到 MVC4 WebApi