简体   繁体   中英

Creating a unit test for CORS with xUnit and .Net Core MVC controller

I want to write a unit test to ensure CORS is on and that a particular WebApi method can only be called from a client that reports to be from a certain domain.

I think I'm running into a common gotcha that's described here, whereby it's not seen as a true cross domain request...

CORS Gotchas

The type of unit test would look something like this...

    [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);
    }

I may have misunderstood things, but can anyone put me right?

First of this isn't a unit test because you are making a call out to some external resource. Unit tests should have any external dependencies mocked/faked out. This is really an integration test.

Also this isn't really testing your code to configure cors, this is testing that cors actually works.

That being said, I tried writing a unit test for CORS and came up with this. Given that I have class that configures CORS

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

        config.EnableCors(cors);
    }
}

Where my AppSettings["CorsClientUrl"] has a value of " https://www.google.com "

So then I want to test that cors is configured after this is called. All my unit test derive from SpecificationBase so that I have a little more BDD style syntax when I write my tests

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

    protected virtual void Given()
    {
    }

    protected virtual void When()
    {
    }
}

public class ThenAttribute : TestAttribute
{
}

And the ultimate unit tests look like this

    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);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM