microsoft / codecoverage

MIT License
79 stars 11 forks source link

Unexpected Code Coverage results with nested records #102

Closed KelvinSweere closed 7 months ago

KelvinSweere commented 7 months ago

Description

I’m in the process of developing a feature that involves nesting one record within another. During my testing phase, I’ve encountered an issue where the code coverage doesn't detect the line coverage for a nested record. I’ve attached a screenshot for reference.

When I modify the nested type from a record to a class, the code coverage behaves as anticipated.

Code

namespace Bff.Application.Meetdata.Queries.GetMeetdata;

public record GetMeetdataResponse(List<MeetdatumViewModel> meetdata)
{
    public List<MeetdatumViewModel> Meetdata { get; set; } = meetdata;
}

public record MeetdatumViewModel
{
    public DateTimeOffset Start { get; set; }
    public decimal Value { get; set; }
}

Screenshot

afbeelding

The IResponse interface isn't needed for reproducing the bug.

mariam-abdulla commented 7 months ago

Hi @KelvinSweere,

In order to achieve 100% coverage of the nested record, you need to use the with operator when creating those objects. The reason you need to do that is that the compiler adds extra methods when generating the IL code.

Please find below an example on how to achieve this:

var meetDatumViewModel = new MeetDatumViewModel();
var anotherMeetDatumViewModel = meetDatumViewModel with { };

For GetMeetdataResponse:

var GetMeetDataResponse = new GetMeetDataResponse(new List<MeetDatumViewModel> { new MeetDatumViewModel() });

var otherGetMeetDataResponse = GetMeetDataResponse with { 
     MeetData = new List<MeetDatumViewModel> { new MeetDatumViewModel() }
};
var otherMeetData = GetMeetDataResponse.MeetData;

var anotherGetMeetDataResponse = GetMeetDataResponse with {
     meetData = new List<MeetDatumViewModel> { new MeetDatumViewModel() } 
};
var anotherMeetData = GetMeetDataResponse.meetData;

With that code, you will be able to achieve 100% coverage.