当前位置:  开发笔记 > 编程语言 > 正文

如何在没有继承的情况下模拟对象(在C中)?

如何解决《如何在没有继承的情况下模拟对象(在C中)?》经验,为你挑选了0个好方法。

我们使用一个简单的对象模型来处理我们的低级网络代码,其中struct指针被传递给假装为方法的函数.我继承了大部分代码,这些代码是由具有可通行的C/C++经验的顾问编写的,我花了很多深夜试图将代码重构为类似于合理结构的东西.

现在我想将代码置于单元测试下,但考虑到我们选择的对象模型,我不知道如何模拟对象.请参阅以下示例:

示例标题(foo.h):

#ifndef FOO_H_
#define FOO_H_

typedef struct Foo_s* Foo;
Foo foo_create(TcpSocket tcp_socket);
void foo_destroy(Foo foo);
int foo_transmit_command(Foo foo, enum Command command);

#endif /* FOO_H_ */

示例源(foo.c):

struct Foo_s {
    TcpSocket tcp_socket;
};

Foo foo_create(TcpSocket tcp_socket)
{   
    Foo foo = NULL;

    assert(tcp_socket != NULL);

    foo = malloc(sizeof(struct Foo_s));
    if (foo == NULL) {
        goto fail;
    }
    memset(foo, 0UL, sizeof(struct Foo_s));

    foo->tcp_socket = tcp_socket;

    return foo;

fail:
    foo_destroy(foo);
    return NULL;
}

void foo_destroy(Foo foo)
{
    if (foo != NULL) {
            tcp_socket_destroy(foo->tcp_socket);
            memset(foo, 0UL, sizeof(struct Foo_s));
            free(foo);
    }
}

int foo_transmit_command(Foo foo, enum Command command)
{
    size_t len = 0;
    struct FooCommandPacket foo_command_packet = {0};

    assert(foo != NULL);
    assert((Command_MIN <= command) && (command <= Command_MAX));

    /* Serialize command into foo_command_packet struct */
    ...

    len = tcp_socket_send(foo->tcp_socket, &foo_command_packet, sizeof(foo_command_packet));
    if (len < sizeof(foo_command_packet)) {
            return -1;
    }
    return 0;
}

在上面的例子中,我想模拟TcpSocket对象,以便我可以在单元测试下引入"foo_transmit_command",但我不确定如何在没有继承的情况下进行此操作.除非我真的需要,否则我真的不想重新设计使用vtable的代码.也许有更好的方法比嘲笑?

我的测试经验主要来自C++,我有点担心我可能会把自己描绘成一个角落.我非常感谢更有经验的测试人员的任何建议.

编辑:
就像Richard Quirk指出的那样,实际上是我要覆盖的"tcp_socket_send"的调用,我更愿意在链接测试时不从库中删除真正的tcp_socket_send符号,因为它是由其他测试调用的.相同的二进制

我开始认为这个问题没有明显的解决方案..

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有