Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Chained Method Calls Across Multiple Lines - Not Covered
MikeHanson
#1 Posted : Monday, June 8, 2015 10:37:56 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/23/2012(UTC)
Posts: 11
Location: St Albans, UK

Was thanked: 3 time(s) in 3 post(s)
When statements that include chained method calls are formatted across multiple lines only the first line is identified as covered, other lines are reported as not covered, which in turn affects coverage metrics calculations.

I have the following in a C# class

var errorMessages = exception.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);

In the editor the SelectMany and Select parts of the statement have a dot indicating the line is not covered, and the metrics window shows the file as being only 95.53% covered

If I reformat the statement so that it is on a single line, the line is marked as covered in the editor and the metrics window shows the file as being 100% covered.

I use ReSharper CleanUp extensively and have it configured to format chained method calls across multiple lines. I personally find this more readable.

I feel NCrunch should recognise this as a single statement, at least for metrics reporting.

Mike Hanson





Remco
#2 Posted : Monday, June 8, 2015 11:37:37 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,123

Thanks: 957 times
Was thanked: 1286 time(s) in 1193 post(s)
Hi Mike,

Thanks for sharing this.

The uncovered lines in this case are identified as code by NCrunch, but because they are implemented using IEnumerable, they won't be executed unless you actually enumerate the errorMessages.

Try adding a .ToList() or .ToArray() to see if this makes any difference.


Cheers,

Remco
MikeHanson
#3 Posted : Monday, June 8, 2015 12:02:12 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/23/2012(UTC)
Posts: 11
Location: St Albans, UK

Was thanked: 3 time(s) in 3 post(s)
Thanks for the quick response Remco.

I understand better now why this occurs, but that suggests there might be something else not quite right.

The very next statement after the aforementioned one is:

var fullErrorMessage = string.Join("; ", errorMessages);

And this statement is recognised as fully covered.

The full method shown below, is a private member of a Repository class and it simply wraps a call to the SaveChanges method of an internal DbContext. All the method does is provide a more informative message, when DbEntityValidationException is caught.

private void SaveChanges()
{
try
{
this.context.SaveChanges();
}
catch (DbEntityValidationException exception)
{
var errorMessages = exception.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);

var fullErrorMessage = string.Join("; ", errorMessages);

var exceptionMessage = string.Concat(exception.Message, " The validation errors are: ", fullErrorMessage);

throw new DbEntityValidationException(exceptionMessage, exception.EntityValidationErrors);
}
}

The only two lines that are flagged as not covered are the Select* lines. In this case I can "fix" the coverage stats by restoring it to a single line (the chances of this class being changed again are very small), which will please the people complaining about the total coverage on the solution being below 95%, but it would be interesting to understand more.

Mike




Remco
#4 Posted : Monday, June 8, 2015 12:21:45 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,123

Thanks: 957 times
Was thanked: 1286 time(s) in 1193 post(s)
Hi Mike,

Are there any error messages in the collection to enumerate?

If the collection is empty, the enumerator will simply return and won't execute the code.

NCrunch is very physical in its method of capturing line-by-line execution data. It has no knowledge of enumerables, lambda expressions, or any language-specific code constructions. It works simply by framing the lines (which are identified by the PDB file) in instrumentation that will capture if/when the corresponding IL is executed.
MikeHanson
#5 Posted : Monday, June 8, 2015 12:30:40 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/23/2012(UTC)
Posts: 11
Location: St Albans, UK

Was thanked: 3 time(s) in 3 post(s)
I see, I will double check the tests to make sure something is returned. I remember when I wrote this some time ago that creating test ValidationError and ValidationResult objects for testing purposes was very messy. So very possible we skipped some tests on the basis of value vs time invested.

Thanks for the explanations though.

Mike
1 user thanked MikeHanson for this useful post.
Remco on 6/8/2015(UTC)
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.049 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download