这似乎很简单,但我似乎无法让它工作.
我有一个带有Save方法的类,它只调用另一个方法ShouldBeCalled().我想验证,如果我调用Save(),其他方法ShouldBeCalled()至少执行一次.我以为我可以做到以下几点.
public class ClassA
{
public virtual void Save()
{
ShouldBeCalled();
}
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
var mockClassA = new Mock<ClassA>();
mockClassA.Object.Save();
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
}
}
Run Code Online (Sandbox Code Playgroud)
但我得到异常"模拟的预期调用至少一次,但从未执行过:x => x.ShouldBeCalled()"
这只是一个猜测,但是Moq用它自己的版本重写了Save()方法,它忽略了我在真实对象的Save()方法中的任何东西.
我在编写测试套件时试图遵循良好的做法.中途我意识到我花了很多(大部分)时间在假物体上...我的大多数测试都是这样的
public interface ITemplateRepository
{
string get GetGenericTemplate {get;}
}
Run Code Online (Sandbox Code Playgroud)
public FakeTemplateRepository : ITemplateRepository
{
public string GetGenericTemplate ()
{
return "<xml>Complex</xml>";
}
}
Run Code Online (Sandbox Code Playgroud)
[Test]
public void CanGetGenericTemplate()
{
ITemplateRepository rep = new FakeTemplateRepository();
Assert.IsNotNull(rep.GetGenericTemplate());
}
Run Code Online (Sandbox Code Playgroud)
[Test]
public void GetGenericTemplateContains()
{
ITemplateRepository rep = new FakeTemplateRepository();
Assert.IsTrue(rep.GetGenericTemplate().StartsWith("<xml>"));
}
Run Code Online (Sandbox Code Playgroud)
我实际上发现自己花了很多时间在FakeTemplateRepository上,确保它返回了我期待的实际内容.这是坏事吗?
这仍然是有效的单元测试吗?单元测试应该快速而简单,不是吗?但老实说,我不太确定,有一点可以肯定的是,它让我思考了数据的形状和内容.FakeRepository中的内容或多或少会反映我的制作内容,尽管是从文件系统中读取而不是在内存中.
如果事实上我正在做的是集成测试,那么我应该如何使用模拟进行单元测试呢?
对我(如果使用Mocks)我没有意义,我设置了期望,以便它调用方法并返回一个字符串?我错过了什么,但我没有看到太多的价值吗?如果我设置了无效的方法名称,代码甚至不会编译!
我真的对整个事情感到困惑,而且我对单元测试的看法现在已经完全模糊了所有这些概念.
任何人都可以用一个超级简单的例子展示假货和模拟如何融入套房吗?例如什么应该是单元测试,什么应该是集成测试?
谢谢