我们使用一个简单的对象模型来处理我们的低级网络代码,其中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符号,因为它是由其他测试调用的.相同的二进制
我开始认为这个问题没有明显的解决方案..