模拟系统调用的建议 [英] Advice on Mocking System Calls

查看:126
本文介绍了模拟系统调用的建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类可以调用 getaddrinfo 进行DNS查找。在测试期间,我想模拟涉及此系统调用的各种错误条件。什么是推荐的方法嘲笑这样的系统调用?我使用Boost.Test进行单元测试。

I have a class which calls getaddrinfo for DNS look ups. During testing I want to simulate various error conditions involving this system call. What's the recommended method for mocking system calls like this? I'm using Boost.Test for my unit testing.

推荐答案

在这种情况下,您不需要模仿 getaddrinfo ,相反,你需要测试而不依赖于它的功能。 Patrick和Noah都有好点,但你至少有两个选项:

In this case you don't need to mock getaddrinfo, rather, you need to test without relying on its functionality. Both Patrick and Noah have good points but you have at least two other options:

因为你已经在一个类中有你的对象,你可以子类来测试。例如,假设以下是你的实际类:

Since you already have your object in a class, you can subclass to test. For example, assume the following is your actual class:

class DnsClass {
    int lookup(...);
};

int DnsClass::lookup(...) {
    return getaddrinfo(...);
}


$ b b
$ b

Then, for testing, you would subclass like this:

class FailingDnsClass {
    int lookup(...) { return 42; }
};

现在可以使用 FailingDnsClass 子类生成错误,但仍然验证在发生错误情况时所有行为正确。依赖注入通常是你的朋友在这种情况下。

You can now use the FailingDnsClass subclass to generate errors but still verify that everything behaves correctly when an error condition occurs. Dependency Injection is often your friend in this case.

注意:这是非常类似于Patrick的答案,但不希望涉及更改生产代码,如果你'

NOTE: This is quite similar to Patrick's answer but doesn't (hopefully) involve changing the production code if you aren't already setup for dependency injection.

在C ++中,您还可以使用链接时间接缝,由Michael Feathers在 使用旧版代码工作 描述。

In C++, you also have link-time seams which Michael Feathers describes in Working Effectively with Legacy Code.

基本思想是利用链接器和构建系统。编译单元测试时,请链接您自己的 getaddrinfo 版本,它将优先于系统版本。例如:

The basic idea is to leverage the linker and your build system. When compiling the unit tests, link in your own version of getaddrinfo which will take precedence over the system version. For example:

test.cpp:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <iostream>

int main(void)
{
        int retval = getaddrinfo(NULL, NULL, NULL, NULL);
        std::cout << "RV:" << retval << std::endl;
        return retval;
}

lib.cpp:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

int getaddrinfo(const char *node, const char *service,
        const struct addrinfo *hints, struct addrinfo **res
        )
{
        return 42;
}

然后进行测试:

$ g++ test.cpp lib.cpp -o test
$ ./test 
RV:42

这篇关于模拟系统调用的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆