使用Lambda Expression或Func委托进行C#Moq单元测试

时间:2016-11-03 13:14:44

标签: c# linq unit-testing testing lambda

我使用Moq和C#进行单元测试。

我有以下实施测试:

var jobsSelectionToMapJobModel = new List<Job>();
var jobsSelectionToMapDataTableModel =
                _enumerableWrapperService.Select(jobsSelectionToMapJobModel,
                    x => _convertJobToJobsModelForDataTableService.Convert(umbracoHelper, x));

_enumerableWrapperService.Select()中的选择方法具有以下签名,如Linq one:

Enumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source,
            Func<TSource, TResult> selector);

我想测试选择器Func委托的内容是否具有正确的逻辑集。 umbracoHelper变量是传递给此方法的外部参数。

如果您使用It.IsAny<Func<TSource, TResult>>(),我们将不会断言逻辑正常。另一方面,我正在考虑使用类似It.Is<Func<TSource,TResult>(func => XXXXXXXX)的东西,但无法弄清楚如何使其工作

见下面的例子:

单元测试示例1

_listToReturn= new List<JobsModelForDataTable>();
_listOfJobs= new List<Job>();
GetMockFor<IEnumerableWrapperService>()
                .Setup(x => x.Select(_listOfJobs,
                     It.IsAny<Func<Job, JobsModelForDataTable>>()))
                .Returns(_listToReturn);

//上面的问题是你没有断言正确的逻辑,因为它接受任何具有相同签名的Func

单位测试示例2

 _listToReturn= new List<JobsModelForDataTable>();
_listOfJobs= new List<Job>();
GetMockFor<IEnumerableWrapperService>()
                .Setup(x => x.Select(_listOfJobs,
                     It.Is<Func<Job, JobsModelForDataTable>>(f => ......)))
                .Returns(_listToReturn);

//这可能是一个选项,但我无法弄清楚如何让它发挥作用

或许我们需要以另一种方式重新思考我们在做什么?

对于我如何测试它,我将不胜感激。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

如果不是实际上不可能以编程方式检查两个表达式是否做同样的事情是相当困难的。因此,最好的办法是将表达式移动到常规的命名方法中并测试该方法:

var jobsSelectionToMapJobModel = new List<Job>();
var jobsSelectionToMapDataTableModel =
                _enumerableWrapperService.Select(jobsSelectionToMapJobModel, ActualMethodToTest);

[...]

internal Something ActualMethodToTest( Job x ) => _convertJobToJobsModelForDataTableService.Convert( _umbracoHelper, x );

并为ActualMethodToTest编写测试,可能使用convertJobToJobsModelForDataTableServiceumbracoHelper的Moq模拟。当然还有_enumerableWrapperService Select的测试。

答案 1 :(得分:0)

在这种情况下,回调函数可能会有所帮助

Func<List<Job>, Job> umbracoHelper = lj => lj.First(); // or any other selection method...
        var listToReturn = new List<JobsModelForDataTable>();
        var listOfJobs = new List<Job>();
        new Mock<IEnumerableWrapperService>().Setup(x => x.Select(listOfJobs, It.IsAny<Func<Job, JobsModelForDataTable>>()))
                                             .Callback<List<Job>, Func<Job, JobsModelForDataTable>>((j, fj) => fj(umbracoHelper(j)))
                                             .Returns(listToReturn);

如果你也为_convertJobToJobsModelForDataTableService使用模拟,你可以验证它