上下文:
我想测试一段旨在在IQueryable<T>
上进行一些操作的代码是否确实如此。但是,当我从已知有效的代码开始,并尝试编写测试以执行该代码时,我得到了一个难以理解的错误。
实际问题:
我想了解该错误,它的含义以及发生的原因。
不是X-Y问题!
此处我对实现我最初目标的最佳方式是什么,或者该测试是否会实现不感兴趣。我要分别问那个问题(link)。在这个问题中,我真正地想知道“此错误甚至意味着什么,以及为什么对于我所了解的基本原理有效的代码会发生这种情况”。
错误消息:
System.ArgumentException : Expression of type '' cannot be used for parameter of type
'System.Linq.IQueryable`1[ADH.Web.API.Tests.Services.QueryableTest+DemoDomainModel]' of method
'System.Linq.IQueryable`1[ADH.Web.API.Tests.Services.QueryableTest+DemoViewModel]
Select[DemoDomainModel,DemoViewModel](System.Linq.IQueryable`1[ADH.Web.API.Tests.Services.QueryableTest+DemoDomainModel],
System.Linq.Expressions.Expression`1[System.Func`2[ADH.Web.API.Tests.Services.QueryableTest+DemoDomainModel,ADH.Web.API.Tests.Services.QueryableTest+DemoViewModel]])'
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
at System.Linq.Queryable.Select[TSource,TResult](IQueryable`1 source, Expression`1 selector)
at ADH.Web.API.Tests.Services.QueryableTest.DemoService.GetAllDemoViewModels() in C:\Work\ADH\ADH\Actuarial Data Hub\ADH.Web.API.Tests\Services\QueryableTest..cs:line 50
at ADH.Web.API.Tests.Services.QueryableTest.CheckQueryableCompiles() in C:\Work\ADH\ADH\Actuarial Data Hub\ADH.Web.API.Tests\Services\QueryableTest..cs:line 71
简化第一行:
System.ArgumentException : Expression of type '' cannot be used for parameter of type
'IQueryable`1[DemoDomainModel]' of method
'IQueryable`1[DemoViewModel] Select[DemoDomainModel,DemoViewModel]
(IQueryable`1[DemoDomainModel], Expression`1[Func`2[DemoDomainModel,DemoViewModel]])'
导致错误的代码和测试(类+单元测试)
using System.Linq;
using NUnit.Framework;
using FakeItEasy;
namespace ADH.Web.API.Tests.Services
{
public class QueryableTest
{
public class DemoDomainModel
{
public int Id { get; set; }
public string Reference { get; set; }
public int ChildId { get; set; }
public DemoChildDomainModel Child { get; set; }
}
public class DemoChildDomainModel
{
public int Id { get; set; }
public string ChildReference { get; set; }
}
public class DemoViewModel
{
public int Id { get; set; }
public string Reference { get; set; }
public string ChildReference { get; set; }
}
public interface IDemoRepository
{
IQueryable<DemoDomainModel> GetAllDemos();
}
public class DemoService
{
private readonly IDemoRepository _demoRepository;
public DemoService(IDemoRepository configRepository)
{
_demoRepository = configRepository;
}
public IQueryable<DemoViewModel> GetAllDemoViewModels()
{
var demos = _demoRepository.GetAllDemos();
return demos.Select(demo => new DemoViewModel()
{
Id = demo.Id,
Reference = demo.Reference,
ChildReference = demo.Child.ChildReference
});
}
}
private DemoService _demoService;
private IDemoRepository _fakeDemoRepository;
[SetUp]
public void Setup()
{
_fakeDemoRepository = A.Fake<IDemoRepository>();
_demoService = new DemoService(_fakeDemoRepository);
}
[Test]
public void CheckQueryableCompiles()
{
_demoService.GetAllDemoViewModels();
}
}
}