gpt4 book ai didi

c# - 如果我想对以表达式作为参数的方法进行单元测试,我应该更改什么?

转载 作者:太空宇宙 更新时间:2023-11-03 15:53:01 25 4
gpt4 key购买 nike

如何为这个方法编写单元测试:

public void ClassifyComments()
{
IEnumerable<Comment> hamComments = _commentRepository.FindBy(x => x.IsSpam == false);
IEnumerable<Comment> spamComments = _commentRepository.FindBy(x => x.IsSpam == true);

//....
}

FindBy 方法将表达式作为参数:

public virtual IEnumerable<T> FindBy(Expression<Func<T, bool>> filter)
{
return dbSet.Where(filter).ToList();
}

到目前为止,这是我的单元测试:

IEnumerable<Comment> spamComments = Builder<Comment>.CreateListOfSize(10).All()
.With(x => x.Content = "spam spam spam")
.Build();
IEnumerable<Comment> hamComments = Builder<Comment>.CreateListOfSize(10).All()
.With(x => x.Content = "ham ham ham")
.Build();


var mockRepository = new Mock<IGenericRepository<Comment>>();
mockRepository
.Setup(x => x.FindBy(It.Is<Expression<Func<Comment, bool>>>(y => y.IsSpam == true)))
.Returns(spamComments);

mockRepository
.Setup(x => x.FindBy(It.Is<Expression<Func<Comment, bool>>>(y => y.IsSpam == true)))
.Returns(hamComments);

但我无法编译它,我该如何更改此测试,以便模拟生成 hamCommentsspamComments 的值。

Error 2 'System.Linq.Expressions.Expression>' does not contain a definition for 'IsSpam' and no extension method 'IsSpam' accepting a first argument of type 'System.Linq.Expressions.Expression>' could be found (are you missing a using directive or an assembly reference?)

最佳答案

您正在尝试重新创建要在测试中测试的逻辑,我认为这是您的错误。试试这个代码:

IEnumerable<Comment> spamComments = Builder<Comment>.CreateListOfSize(10).All()
.With(x => x.Content = "spam spam spam")
.Build();
IEnumerable<Comment> hamComments = Builder<Comment>.CreateListOfSize(10).All()
.With(x => x.Content = "ham ham ham")
.Build();

// Bring both lists together as one (might be a better way to do this)
IEnumerable<Comment> allComments = spamComments.Union(hamComments);

var mockRepository = new Mock<IGenericRepository<Comment>>();
mockRepository
.Setup(x => x.FindBy(It.Is<Expression<Func<Comment, bool>>>())
.Returns(spamComments);

注意:我不是 Moq 专家,所以上面的语法可能不是 100% 正确

因此,您的 ClassifyComments 方法中的代码的目的是获取混合 Comment 实例的列表,并将它们分成不同的分类(垃圾邮件和非垃圾邮件),所以您只希望您的 mockRepository 返回单个评论列表。

然后由您的单元测试的其余部分来验证您的 ClassifyComments 在知道它有 10 个“垃圾邮件”和 10 个“垃圾邮件” 的情况下做了它应该做的事情注释实例。

举个例子,我们假设您的 ClassifyComments 如下所示:

public void ClassifyComments(out IEnumerable<Comment> spam, out IEnumerable<Comment> ham)
{
IEnumerable<Comment> hamComments = _commentRepository.FindBy(x => x.IsSpam == false);
IEnumerable<Comment> spamComments = _commentRepository.FindBy(x => x.IsSpam == true);

//....

// Set the out params
spam = spamComments;
ham = hamComments;
}

你的单元测试看起来像这样:

public void TestClassifyComments() {
IEnumerable<Comment> spamComments = Builder<Comment>.CreateListOfSize(10).All()
.With(x => x.Content = "spam spam spam")
.Build();
IEnumerable<Comment> hamComments = Builder<Comment>.CreateListOfSize(10).All()
.With(x => x.Content = "ham ham ham")
.Build();

// Bring both lists together as one (might be a better way to do this)
IEnumerable<Comment> allComments = spamComments.Union(hamComments);

var mockRepository = new Mock<IGenericRepository<Comment>>();
mockRepository
.Setup(x => x.FindBy(It.Is<Expression<Func<Comment, bool>>>())
.Returns( (Expression<Func<Comment, bool>> predicate => spamComments.Where(predicate));

// Construct the class which has the ClassifyComments method
var sut = ...;

IEnumerable<Comment> ham;
IEnumerable<Comment> spam;
sut.ClassifyComments(out spam, out ham);

Assert.That(spam.Length, Is.EqualTo(10));
Assert.That(ham.Length, Is.EqualTo(10));
}

编辑

好吧,我对 Moq 做了一点研究,我认为上面的代码是你如何使用 Moq 来做到这一点。

关于c# - 如果我想对以表达式作为参数的方法进行单元测试,我应该更改什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24980365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com