交互测试用来测试一个对象如何向另一个对象传递消息,或者如何从其他对象接收消息,即测试对象如何与其他对象进行交互。
模拟对象是系统中的一个伪对象,用来决定一个单元测试是通过还是失败。它通过验证被测对象和伪对象之间是否进行预期的交互来判断。通常每个测试只有一个伪对象。
桩对象和模拟对象的区别:使用桩对象时,断言是针对被测类执的。使用模拟对象时,断言是针对模拟对象的。
下面通过实际例子,演示模拟对象的使用。
1.被测试类
LogAnalyzer类接收到一个长度太短的文件名时,就发送一个错误信息给一个外部的web服务。
public class LogAnalyzer
{
private IwebService service;
public LogAnalyzer(IwebService service)
{
this.service = service;
}
public void Analyzer(string fileName)
{
if (fileName.Length < 6)
{
service.LogError("Filename too short:" + fileName);
}
}
}
2.模拟对象
模拟对象MockService模拟web服务,接收LogAnalyzer发出的信息,然后针对接受的信息进行断言。
接口的定义如下:
public interface IwebService
{
void LogError(string message);
}
模拟对象的定义如下:
public class MockService : IwebService
{
public string LastError;
public void LogError(string message)
{
LastError = message;
}
}
3.测试代码
测试的目的是测试LogAnalyzer和web服务器之间的交互。断言是针对模拟对象,而不是针对LogAnalyzer类。
[TestFixture]
public class LogAnalyzerTests
{
[Test]
public void Analyze_TooShortFileName_CallsWebService()
{
MockService mockService = new MockService();
LogAnalyzer log = new LogAnalyzer(mockService);
log.Analyzer("s.log");
//对模拟对象的断言
Assert.AreEqual("Filename too short:s.log",mockService.LastError);
}
}