Unit testing 在单元测试中,您是否验证和断言?
我在单元测试项目中使用Moq。我在网上看到的大多数单元测试示例都以Unit testing 在单元测试中,您是否验证和断言?,unit-testing,moq,Unit Testing,Moq,我在单元测试项目中使用Moq。我在网上看到的大多数单元测试示例都以someMock.VerifyAll()结尾我想知道在VerifyAll()之后断言是否可以。那么比如说, //排列 var student=newstudent{Id=0,Name=“John Doe”,IsRegistered=false}; var studentRepository=new Mock(); var studentService=newstudentservice(studentRepository.Obje
someMock.VerifyAll()结尾
我想知道在VerifyAll()
之后断言是否可以。那么比如说,
//排列
var student=newstudent{Id=0,Name=“John Doe”,IsRegistered=false};
var studentRepository=new Mock();
var studentService=newstudentservice(studentRepository.Object);
//表演
学生服务。注册(学生)// 是的,你应该调用断言
VerifyAll()
将断言所有SetUp()
调用都已实际调用
VerifyAll()
不会确认您的学生对象已注册。因为您的测试用例中没有SetUp()
调用,所以我认为VerifyAll()
并不是在验证任何东西。不,在大多数情况下,您不应该同时使用这两个调用(总是有例外)。原因是您应该在测试中只测试一件事情,以确保可维护性、可读性和其他一些原因。因此,在测试中应该是Verify(VerifyAll)或Assert,并相应地命名测试
看看Roy Osherove的文章:
VerifyAll
用于确保调用某些方法以及调用次数。您可以使用mock
Assert
用于验证正在测试的方法返回的结果。您可以使用存根
Martin fowler有一篇很好的文章解释了mock和stub之间的区别。如果你理解它,你就会更好地了解其中的区别
更新:下面的评论中要求使用Moq的模拟vs存根示例。我使用了Verify,但您也可以使用VerifyAll
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用最小起订量;
...
[测试类]
公共类UnitTest1
{
///
///使用Mock进行测试,以验证GetNameWithPrefix方法调用
///Id大于零时存储库GetName方法一次
///
[测试方法]
public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
{
//安排
var mockEntityRepository=new Mock();
mockEntityRepository.Setup(m=>m.GetName(It.IsAny());
var entity=新的EntityClass(mockEntityRepository.Object);
//表演
var name=entity.GetNameWithPrefix(12);
//断言
mockEntityRepository。验证(
m=>m.GetName(It.IsAny()),Times.one);
}
///
///使用Mock进行测试,以验证GetNameWithPrefix方法
///Id为零时不调用存储库GetName方法
///
[测试方法]
public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
{
//安排
var mockEntityRepository=new Mock();
mockEntityRepository.Setup(m=>m.GetName(It.IsAny());
var entity=新的EntityClass(mockEntityRepository.Object);
//表演
var name=entity.GetNameWithPrefix(0);
//断言
mockEntityRepository。验证(
m=>m.GetName(It.IsAny()),Times.Never);
}
///
///使用存根测试以验证GetNameWithPrefix方法
///返回带有前缀的名称
///
[测试方法]
public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
{
//安排
var stubEntityRepository=new Mock();
stubEntityRepository.Setup(m=>m.GetName(It.IsAny()))
.申报单(“存根”);
常量字符串应为带有前缀的\u NAME\u=“Mr.Stub”;
var entity=新的EntityClass(stubEntityRepository.Object);
//表演
var name=entity.GetNameWithPrefix(12);
//断言
Assert.AreEqual(应为带有前缀的名称);
}
}
公共类实体类
{
私营企业报告机构(实体报告机构);;
公共实体类(entityRepository entityRepository)
{
这个._entityRepository=entityRepository;
}
公共字符串名称{get;set;}
公共字符串GetNameWithPrefix(int id)
{
string name=string.Empty;
如果(id>0)
{
name=this.\u entityRepository.GetName(id);
}
返回“先生”+姓名;
}
}
公共接口智能存储库
{
字符串GetName(int-id);
}
公共类实体存储库:IENTITY存储库
{
公共字符串GetName(int-id)
{
//用于连接到DB并根据Id获取名称的代码
返回“NameFromDb”;
}
}
在模拟测试中断言和验证都没有本质上的错误,尽管依赖于被调用的实际方法的断言可能会失败,因为模拟方法的效果与实际方法不同
在您的示例中,这可能很好,因为只有存储库被模拟,学生状态的更改可能是在服务中完成的
验证和断言是否应该在同一个测试中进行,在某种程度上取决于用户的喜好。实际上,verify是检查是否对存储库进行了正确的调用,assert是检查是否对实体进行了正确的更改。由于这些是单独的关注点,我会将它们放在单独的测试中,但那可能就是我。我绝对希望看到在单元测试中,验证
和断言
并排使用。断言用于验证被测系统的属性是否已正确设置,而Verify
用于确保被测系统接受的任何依赖项都已正确调用。使用Moq
时,我倾向于显式验证设置,而不是使用VerifyAll
catch all。这样,您就可以更清楚地了解测试的意图
我假设在上面的代码中,您对学生存储库的调用返回一个布尔值,表示学生已注册?然后在student上设置该值<