Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 在单元测试中,您是否验证和断言?_Unit Testing_Moq - Fatal编程技术网

Unit testing 在单元测试中,您是否验证和断言?

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

我在单元测试项目中使用Moq。我在网上看到的大多数单元测试示例都以
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上设置该值<