我是制作单元测试的新手。我刚刚开始介绍一些简单的类和功能。
但是我在更复杂的情况下遇到了一些问题。
例如:
我有一个方法"ResultObject getServerStatus(string ip,string user,string pass,...)"
并在此方法中,对服务器进行SSH连接,并完成多项检查。
测试(模拟)诸如“SSH连接和与SSH Shell的交互”之类的依赖关系或“SNMP请求”之类的东西的正确方法是什么?显然在我的测试环境中没有服务器可以检查或SNMP设备。
测试这种复杂场景的正确方法是什么?你能指出一些这样的依赖关系的好例子吗?
答案 0 :(得分:0)
您必须在班级中分离第三方逻辑。
示例:强>
public class MyClass
{
private SshMagic _sshMagic = new SshMagic(); // or something like that
...
ResultObject getServerStatus(string ip,string user,string pass,...)
{
if (..)
{
return _sshMagic.Something();
}
else
{
...
}
}
}
你要测试的是你的代码:条件,循环等。return _sshMagic.Something()
行是一个外部逻辑,你绝对不想测试它。
在界面后面包装SshMagic。这有两个好处:
1)你可以随时更改实现(比如出现不同API的新版本,所以你只需重写你的包装器:所有其他代码可能不需要一点改动)
2)它总是很有可能创建一个适配器并专注于你想要做的事情而不是实现细节,例如SshMagic类。示例:如果您从不在方法中使用4个参数中的2个参数,则可以隐藏它们,或者如果您一起调用3个方法,则可以将它们包装在一个方法中...
示例:强>
public interface ISshMagic
{
...
ResultObject Something();
...
}
public class MyClass
{
private ISshMagic _sshMagic;
public MyClass(ISshMagic sshMagic)
{
_sshMagic = sshMagic;
}
...
}
现在我们已经分离了依赖关系,我们将嘲笑这个混蛋。你必须选择一个模拟框架,如Moq,Simple.Mocking等。为了举例,我将在这里使用Simple.Mocking。
示例强>
您可以在此处创建MockObject:
[TestFixture]
public class UnitTesty
{
...
[Test]
public void GetServerStatus_Will_Call_Something_Of_SshMagic()
{
...
_mockSshMagic = Mock.Interface<ISshMagic>();
MyClass myClass = new MyClass(_mockSshMagic);
...
// we are setting up that _mockSshMagic.Something() will be called
Expect.Once.MethodCall(() => _mockSshMagic.Something());
...
// do your test here...
myClass.("255.255.255.0", "Me", "MyPassword", ...);
...
// we are checking that our expectations were met:
AssertInvocationsWereMade.MatchingExpectationsFor(_mockSshMagic);
}
}