单元测试?使用模拟对象做交互测试
作者:网络转载 发布时间:[ 2014/6/9 13:56:54 ] 推荐标签:单元测试 模拟对象 交互测试
这里我们定义了一个对象TestLog对象,该对象是一个模拟对像,继承了ILog接口。该测试中,一共进行了两项测试。一项是:验证用户名和密码是否输入正确。另一项是:验证用户写入日志的信息是否正确(比如应该写入用户名,结果把密码写入了日志,测试会无法通过)。
这里我们区分一下模拟对象与桩对象。上一节中,我们讲过桩对象的定义,那么模拟对象与桩对象是什么关系呢?
模拟对象与桩对象在写法上区别很小,关键在于模拟对象需要进行断言,也是说模拟对象可以导致测试失败。桩对象只是为了方便测试所定义的一个对象,不需要进行断言,所以,桩对象永远不会导致测试失败。
上面的测试中,如果我们去掉后一行代码,即我们不进行写入日志的断言,则该对象是一个桩对象。
Assert.AreEqual(log.Message, userNmae);
上面的模拟对象是我们自己写的,自己写模拟对象比较费时,我们可以使用模拟框架进行编写。这里我使用了Rhino Mocks框架。如果要执行下面的代码,需要下载Rhino.Mocks.dll文件,然后直接引用即可。
测试框架这里我选用了NUnit框架。测试代码如下:
[TestFixture]
public class MyLoginTest
{
[Test]
public void Mock_Vaild_Test()
{
MockRepository mock = new MockRepository();
var log = mock.DynamicMock<ILog>();
var userName = "admin";
var passWord = "123456";
using (mock.Record())
{
log.Write(userName);
}
MyLogin login = new MyLogin();
login.Log = log;
var isLogin = login.Valid(userName, passWord);
Assert.AreEqual(isLogin, true);
mock.VerifyAll();
}
|
这里我没有编写一个类去继承ILog接口,而是通过模拟框架,动态生成了一个ILog对象。代码是这句:
MockRepository mock = new MockRepository();
var log = mock.DynamicMock<ILog>();
这里便生成了Log对象。通过录制-回放的模式进行模拟对象测试,首先需要定义我们的期望行为,后验证实际行为与期望行为是否一致。这里,需要录制我们期望行为,代码如下:
using (mock.Record())
{
log.Write(userName);
}
|
这里我们期望向日志中写入用户名。再通过回放来进行验证,代码如下:
mock.VerifyAll();
该方法会验证,期望向日志中写入的信息与实际向日志中写入的信息是否一致,如果不一致,测试失败。
这里我们便完成了使用模拟框架进行单元测试。如果我们不需要测试日志写入方法,则把模拟对象换成桩对象可以了,生成桩对象的方法如下:
MockRepository mock = new MockRepository();
var log = mock.Stub<ILog>();
把回放的方法(mock.VerifyAll())去掉,完成了模拟对象向桩对象的转变。注意,这里录制的代码还是需要的。
总结:编写模拟对象和桩对象是非常有意义的,使用框架可以帮助我们简化单元测试。一般情况下,一个测试中,可以有多个桩对象,但好只有一个模拟对象。模拟对象太多,证明一个测试方法做了太多项测试,不利于维护测试代码,一旦代码变改,很容易使单元测试失败。
下一节,写一下测试框架的一些常用功能,如:如何模拟异常、如何模拟返回值等。。。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11