1

我是制作单元测试的新手。我刚开始使用一些简单的类和功能。

但是我在更复杂的情况下遇到了一些问题。

例如:

我有一个方法"ResultObject getServerStatus(string ip,string user,string pass,...)"

并在此方法中与服务器建立 SSH 连接并完成多项检查。

测试(模拟)诸如“SSH 连接和与 SSH Shell 的交互”或“SNMP 请求”之类的依赖项的正确方法是什么?显然,在我的测试环境中,没有服务器可以检查或 SNMP 设备。

测试这种复杂场景的正确方法是什么,你能指出一些这样的依赖关系的好例子吗?

4

1 回答 1

1

您将不得不在您的类中分离第三方逻辑。

例子:

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 类。示例:如果您从未在一个方法中使用四个参数中的两个参数,则可以隐藏它们,或者如果您同时调用 3 个方法,则可以将它们包装在一个方法中...

例子:

public interface ISshMagic
{
    ...
    ResultObject Something();
    ...   
}

public class MyClass
{
    private ISshMagic _sshMagic;

    public MyClass(ISshMagic sshMagic)
    {
        _sshMagic = sshMagic;
    }

    ...
}

第二步

现在我们已经分离了依赖关系,我们将模拟这个混蛋。您必须选择一个模拟框架,例如MoqSimple.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);
    }
}
于 2013-10-17T11:52:53.240 回答