Non è possibile - se il test dell'unità significa che si sta utilizzando un repository falso in memoria e si sta quindi utilizzando LINQ to Objects. Se collaudi le tue query con LINQ to Objects, non hai testato la tua applicazione ma solo il tuo repository fasullo.
L'eccezione è il caso meno pericoloso in quanto indica che si dispone di un test rosso, ma probabilmente in realtà un'applicazione funzionante.
Più pericoloso è il caso al contrario: test verde ma un'applicazione o query che non restituiscono gli stessi risultati del test. Le query come ...
context.MyEntities.Where(e => MyBoolFunction(e)).ToList()
o
context.MyEntities.Select(e => new MyEntity { Name = e.Name }).ToList()
... funzioneranno bene nel test, ma non con LINQ to Entities nella vostra applicazione.
una query come ...
context.MyEntities.Where(e => e.Name == "abc").ToList()
... sarà potenzialmente restituire risultati diversi con LINQ to Objects di LINQ to Entities.
È possibile testare solo questa e la query nella domanda creando test di integrazione che utilizzano il provider LINQ to Entities dell'applicazione e un database reale.
Modifica
Se avete ancora voglia di scrivere unit test Penso che tu debba falso query stessa o almeno espressioni nella query. Potevo immaginare che qualcosa sulla falsariga del seguente codice potrebbe funzionare:
creare un'interfaccia per la Where
espressione:
public interface IEntityExpressions
{
Expression<Func<MyEntity, bool>> GetSearchByDateExpression(DateTime date);
// maybe more expressions which use EntityFunctions or SqlFunctions
}
Creare un'implementazione per l'applicazione ...
public class EntityExpressions : IEntityExpressions
{
public Expression<Func<MyEntity, bool>>
GetSearchByDateExpression(DateTime date)
{
return e => EntityFunctions.TruncateTime(e.Date) == date;
// Expression for LINQ to Entities, does not work with LINQ to Objects
}
}
...e una seconda implementazione nel progetto di test Unità:
public class FakeEntityExpressions : IEntityExpressions
{
public Expression<Func<MyEntity, bool>>
GetSearchByDateExpression(DateTime date)
{
return e => e.Date.Date == date;
// Expression for LINQ to Objects, does not work with LINQ to Entities
}
}
Nella classe in cui si utilizza la query creare un membro privato di questa interfaccia e due costruttori:
public class MyClass
{
private readonly IEntityExpressions _entityExpressions;
public MyClass()
{
_entityExpressions = new EntityExpressions(); // "poor man's IOC"
}
public MyClass(IEntityExpressions entityExpressions)
{
_entityExpressions = entityExpressions;
}
// just an example, I don't know how exactly the context of your query is
public IQueryable<MyEntity> BuildQuery(IQueryable<MyEntity> query,
SearchOptions searchOptions)
{
if (searchOptions.Date.HasValue)
query = query.Where(_entityExpressions.GetSearchByDateExpression(
searchOptions.Date));
return query;
}
}
Utilizzare il primo (di default) costruttore nell'applicazione:
var myClass = new MyClass();
var searchOptions = new SearchOptions { Date = DateTime.Now.Date };
var query = myClass.BuildQuery(context.MyEntities, searchOptions);
var result = query.ToList(); // this is LINQ to Entities, queries database
utilizzare il secondo costruttore con FakeEntityExpressions
nel vostro unit test:
Se si utilizza un contenitore di dipendenze per iniezione, è possibile sfruttarlo iniettando l'implementazione appropriata se IEntityExpressions
nel costruttore e non è necessario il costruttore predefinito.
Ho testato il codice di esempio sopra e ha funzionato.
ho cancellato la mia risposta, non era utile per voi. In qualche modo sospettavo che non ti stavo dicendo niente di nuovo. Non ho idea di come gestire la tua query in un test unitario, a meno di non mettere un'intera query dietro un'interfaccia implementata LTO-friendly ('c => c.Date.Date == ...') nel tuo test unitario . – Slauma
Potresti per favore annullare l'eliminazione della risposta? Penso che sia abbastanza valido e possa aiutare gli altri ... –
Il metodo è solo un segnaposto. Quando il traduttore Linq to Entity elabora l'albero delle espressioni se vede questo metodo, sa come sostituirlo con un costrutto specifico del database. Pertanto, il metodo stesso non ha alcuna implementazione ma getta NotSupportedException. – Pawel