dotnet / dotnet/efcore

Consider having AssertTranslation that tests both predicate and projection

Open
#35,318 0 comments 0 reactions 0 assignees View on GitHub
area-test customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

When testing e.g. a function translation, for full coverage we need to check both predicate translation (with the function in Where()), and projection (with the function in Select()).

* Testing Select() is insufficient because EF client evaluates final select (and so translation isn't even tested); even without this, Select() wouldn't check that the translation returns the correct relational value, only that what it returns can be projected out and read.
* Testing Where() ensures that actual translation occurs, and also that the proper relational value is produced (since we compare the translation result to e.g. some constant). However, it does not check that e.g. the correct CLR type is set on the resulting SqlExpression; thus, a correctly translated function can fail when projected out of the database.

In the base, we've sometimes done both Where and Select tests for the same function translation. We've done this very sporadically and non-systematically, with very few translations getting both and most getting only one or the other.

To do this more systematically, we could have an AssertTranslation, which accepts a query base, a lambda to be tested, and an expected result value for the Where test; AssertTranslation would then do AssertQuery twice internally, once for Where and once for Select. For example:

```c#
await AssertTranslation(async, ss => ss.Set(), b => Math.Cos(b.Double), b => 8);
```

This would internally perform the following two things:

```c#
await AssertQuery(async, ss => ss.Set().Where(b => Math.Cos(b.Double) == 8);
await AssertQuery(async, ss => ss.Set().Select(b => Math.Cos(b.Double));
```

In the meantime, where we think it's important to test both Where and Select, we should simply combine both into the same test; so the single test that covers the translation for Func() can call AssertQuery twice. If and when we have AssertTranslation, it would basically do the same.

/cc @maumar

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.