Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the culture in a dotnetcore xunit test

I have the following unit test that I'm porting from a .Net Framework library to .Net core xunint test library. The project the unit test needs to be added to is

https://github.com/dotliquid/dotliquid

and is being added to the selected file as show here

enter image description here

The unit test I'm trying to add is

[Test]
public void ParsingWithCommaDecimalSeparatorShouldWork()
{
    var ci = new CultureInfo(CultureInfo.CurrentCulture.Name)
             {
                 NumberFormat =
                 {
                     NumberDecimalSeparator = ","
                     , NumberGroupSeparator = "."
                 }
             };
    Thread.CurrentThread.CurrentCulture = ci;

    var t = Template.Parse("{{2.5}}");
    var result = t.Render( new Hash(), CultureInfo.InvariantCulture );
    Assert.AreEqual( result, "2.5"   );
}

However the test fails to compile in dotnet core.

Severity Code Description Project File Line Suppression State Error CS1061 'Thread' does not contain a definition for 'CurrentCulture' and no extension method 'CurrentCulture' accepting a first argument of type 'Thread' could be found (are you missing a using directive or an assembly reference?) DotLiquid.Tests(net451) C:\Users\phelan\workspace\dotliquid\src\DotLiquid.Tests\OutputTests.cs 113 N/A

I need to have different unit tests with different cultures. I would like to create an XUnit theory where each instance passes in a different culture for the unit test to verify against. How is this done in .NetCore?

like image 351
bradgonesurfing Avatar asked Sep 13 '17 13:09

bradgonesurfing


People also ask

What is InlineData in xUnit?

[InlineData] allows us to specify that a separate test is run on a particular Theory method for each instance of [InlineData] .

What is test fixture in xUnit?

In xUnit, a test fixture is all the things we need to have in place in order to run a test and expect a particular outcome. Some people call this the test context.


1 Answers

I looked at some of the dotnet source and I found this.

CultureInfo.DefaultThreadCurrentCulture = ci;

Basically it looks like you can set the default thread current culture from a static property of CultureInfo rather than from Thread.CurrentThread

poking around a bit more I found this

public CultureInfo CurrentCulture
{
    get
    {
        Contract.Ensures(Contract.Result<CultureInfo>() != null);
        return CultureInfo.CurrentCulture;
    }

    set
    {
        Contract.EndContractBlock();

        // If you add more pre-conditions to this method, check to see if you also need to 
        // add them to CultureInfo.DefaultThreadCurrentCulture.set.

        if (m_CurrentCulture == null && m_CurrentUICulture == null)
            nativeInitCultureAccessors();

        CultureInfo.CurrentCulture = value;
    }
}

This is in Thread.cs. So you can set the CultureInfo.CurrentCulture property explicitly.

example:

CultureInfo.CurrentCulture = new CultureInfo("en-GB"); ;

Assert.Equal("£1,000.00", String.Format("{0:C}", 1000));

CultureInfo.CurrentCulture = new CultureInfo("en-US"); ;

Assert.Equal("$1,000.00", String.Format("{0:C}", 1000));

enter image description here

csproj file for unit test project:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.0</TargetFramework>

    <IsPackable>false</IsPackable>

    <ApplicationIcon />

    <OutputType>Library</OutputType>

    <StartupObject />
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170425-07" />
    <PackageReference Include="xunit" Version="2.2.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
  </ItemGroup>

</Project>
like image 52
Aaron Roberts Avatar answered Sep 21 '22 06:09

Aaron Roberts