7

I have a function using a socket and I would mock it but I couldn't find how to do it.

Is there a way to mock sockets in C?

Thanks

pBouillon
  • 268
  • 4
  • 14
  • Definitely C, not C++, yes? Method is a C++ term. – Joe May 19 '17 at 15:09
  • Yeah right, bad term, I meant function – pBouillon May 19 '17 at 15:09
  • @Joe I'd say that in C, method is a synonym. – Badda May 19 '17 at 15:11
  • @Badda It is, but it is also the sign of someone being confused and actually asking about C++ instead of C (on SO at least!). I just wanted clarification. – Joe May 19 '17 at 15:13
  • 1
    @Badda: A _method_ is a _function_ , but not vice-versa! – too honest for this site May 19 '17 at 15:17
  • 2
    I disagree, @Badda. There is no term "method" in C's lexicon. In C++, where the term *is* meaningful, it designates something that has no C analog. I grant that we ordinarily understand what someone means when they say "method" in C context, but it is not a *bona fide* synonym for "function". Its use is a possible symptom of muddled thinking, whether confusion between C and C++ or something else. – John Bollinger May 19 '17 at 15:19
  • To be pedantic: the term "method" isn't actually part of C++'s lexicon either. It's a generic OO term. In C++ the proper terminology is "member function". – Human-Compiler Jun 30 '20 at 19:44

2 Answers2

12

Most system / library function are weak symbols. That means you can create your own implementation of them that will override the existing versions. You can then use these functions when unit testing.

Suppose you want to test the following function:

src.c:

int get_socket()
{
    int s;

    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s == -1) {
        perror("socket failed");
    } else {
        printf("socket success\n");
        close(s);
    }
    return s;
}

You would then create the mock function (and any controlling variables) in a separate source file:

mock_socket.c:

int sock_rval;

int socket(int domain, int type, int protocol)
{
    printf("calling mock socket\n");
    return sock_rval;
}

Then in another file you have your test:

test_socket.c:

extern int sock_rval;
int get_socket();

int main()
{
    sock_rval = -1;
    int rval = get_socket();
    assert(rval == -1);
    sock_rval = 3;
    int rval = get_socket();
    assert(rval == 3);
    return 0;
}

You would then compile and link these three modules together. Then get_socket will call the socket function in mock_socket.c instead of the library function.

This technique works not just with socket functions, but with system / library functions in general.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

Sockets are managed by the kernel, so there is no userspace-only mechanism for mocking them, but you can set up a genuine socket connected to an endpoint that's part of your test fixture.

In particular, you may be able to use a unix-domain or raw socket for that purpose where the code under test normally has, say, a TCP socket to work with, or you can connect a socket back to the local test fixture via the loopback interface. Or, though I am unaware of any example, in principle you could also find or write a driver that provides sockets for an artificial, for-purpose address family.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157