Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# 8.0 unit test switch expression not covered

I am using C# 8.0 which supports switch expression for my project. I am recently building an unit test project and generate code coverage report. But there seems to be a problem with all switch expressions. I have some lines similar to following in my code:

private static string GenerateRequestUrl(Language language, WeatherDataType dataType) {
    var url = "https://data.weather.gov.hk/weatherAPI/opendata/weather.php?";

    url += language switch {
        Language.English => "lang=en",
        Language.TraditionalChinese => "lang=tc",
        Language.SimplifiedChinese => "lang=sc",
        _ => "lang=en"
    };

    url += dataType switch {
        WeatherDataType.LocalWeatherForecast => "&dataType=flw",
        WeatherDataType.NineDaysWeather => "&dataType=fnd"
    };

    return url;
}

And my test method covers all situations above, but the report shows those lines with switch expressions are not covered. Like in this image: Coverage Highlights in JetBrains Rider

What should I do to make them covered.

like image 487
shingzh Avatar asked Jun 09 '26 00:06

shingzh


1 Answers

Although it may not be the answer you hoped for, it seems that the code coverage doesn't work with non-sequential switch expressions.

When you look at the IL Code, the new C# 8.0 switch expression is first calculating (jumping) which expression is true and then setting the url.
Whereas the sequential switch statement sets the url after the case statement.

So if you want a full coverage you should use the sequential switch statement (like for the WeatherDataType in the code below).

Code

enter image description here

IL Code

    .method public hidebysig static string  GenerateRequestUrl(valuetype Demo.Generator/Language language,
                                                           valuetype Demo.Generator/WeatherDataType dataType) cil managed
{
  // Code size       130 (0x82)
  .maxstack  2
  .locals init (string V_0,
           string V_1,
           string V_2,
           valuetype Demo.Generator/WeatherDataType V_3,
           valuetype Demo.Generator/WeatherDataType V_4,
           string V_5)
  IL_0000:  nop
  IL_0001:  ldstr      "https://data.weather.gov.hk/weatherAPI/opendata/we"
  + "ather.php\?"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ldc.i4.1
  IL_000a:  brtrue.s   IL_000d
  IL_000c:  nop
  IL_000d:  ldarg.0
  IL_000e:  switch     ( 
                        IL_0021,
                        IL_0029,
                        IL_0031)
  IL_001f:  br.s       IL_0039
  IL_0021:  ldstr      "lang=en"
  IL_0026:  stloc.2
  IL_0027:  br.s       IL_0041
  IL_0029:  ldstr      "lang=tc"
  IL_002e:  stloc.2
  IL_002f:  br.s       IL_0041
  IL_0031:  ldstr      "lang=sc"
  IL_0036:  stloc.2
  IL_0037:  br.s       IL_0041
  IL_0039:  ldstr      "lang=en"
  IL_003e:  stloc.2
  IL_003f:  br.s       IL_0041
  IL_0041:  ldc.i4.1
  IL_0042:  brtrue.s   IL_0045
  IL_0044:  nop
  IL_0045:  ldloc.1
  IL_0046:  ldloc.2
  IL_0047:  call       string [System.Runtime]System.String::Concat(string,
                                                                    string)
  IL_004c:  stloc.0
  IL_004d:  ldarg.1
  IL_004e:  stloc.s    V_4
  IL_0050:  ldloc.s    V_4
  IL_0052:  stloc.3
  IL_0053:  ldloc.3
  IL_0054:  brfalse.s  IL_005e
  IL_0056:  br.s       IL_0058
  IL_0058:  ldloc.3
  IL_0059:  ldc.i4.1
  IL_005a:  beq.s      IL_006c
  IL_005c:  br.s       IL_007a
  IL_005e:  ldloc.0
  IL_005f:  ldstr      "&dataType=flw"
  IL_0064:  call       string [System.Runtime]System.String::Concat(string,
                                                                    string)
  IL_0069:  stloc.0
  IL_006a:  br.s       IL_007a
  IL_006c:  ldloc.0
  IL_006d:  ldstr      "&dataType=fnd"
  IL_0072:  call       string [System.Runtime]System.String::Concat(string,
                                                                    string)
  IL_0077:  stloc.0
  IL_0078:  br.s       IL_007a
  IL_007a:  ldloc.0
  IL_007b:  stloc.s    V_5
  IL_007d:  br.s       IL_007f
  IL_007f:  ldloc.s    V_5
  IL_0081:  ret
} // end of method Generator::GenerateRequestUrl
like image 150
hce Avatar answered Jun 10 '26 12:06

hce