13

Here is a typical C++ code:

foo.hpp

#pragma once

class Foo {
public:
  void f();
  void g();
  ...
};

foo.cpp

#include "foo.hpp"

namespace {
    const int kUpperX = 111;
    const int kAlternativeX = 222;

    bool match(int x) {
      return x < kUpperX || x == kAlternativeX;
    }
} // namespace

void Foo::f() {
  ...
  if (match(x)) return;
  ...

It looks like a decent idiomatic C++ code - a class, a helper function match which is used by the methods of Foo, some constants for that helper function.

And then I want to write tests.
It would be perfectly logical to write a separate unit test for match, because it's quite non-trivial.
But it resides in an anonymous namespace.
Of course I can write a test which would call Foo::f(). However it won't be a good test if Foo is heavy and complicated, such test won't isolate the testee from other unrelated factors.

So I have to move match and everything else out of the anonymous namespace.

Question: what's the point of putting functions and constants into the anonymous namespace, if it makes them unusable in tests?

  • 3
    @BЈовић re-read the code – the anonymous namespace is in foo.cpp, not the header! OP seems to understand quite well that you shouldn't put anon namespaces in a header. – amon Jan 12 '16 at 17:14
  • Some idea in Unit Testing C++ Code in an Unnamed Namespace... but the "point" is that encapsulation is good. After all it's the same problem you have with private member functions: they cannot be tested nonintrusively, but you don't want to give up information hiding for unit testing (e.g. stackoverflow.com/a/3676680/3235496). – manlio Jan 13 '16 at 10:32
  • 1
    You case is conceptually not very different from the case of testing (or not testing) private methods. So when you search for "unit test private" here on Programmers, you will get lots of answers you can apply directly to your case. – Doc Brown Jan 13 '16 at 12:28
  • @DocBrown I'm not asking how to test functions in anon. namespaces. I'm asking "why put code into anon. namespaces?" (see the text at the end of the question). Blame Ixrec for changing the title to something different. – Abyx Jan 13 '16 at 12:56
  • 1
    @Abyx: in those other answers I mentioned above, you will find a big consensus of many experts here that it is a really bad idea to test private methods, and that abusing the friend keyword for that purpose is not recommended.Combine that with your assumption that if a restriction for a method leads to a situation where you cannot test it directly any more, that would imply private methods were not useful. – Doc Brown Jan 13 '16 at 15:18
5

The function in your example looks quite complex, and it may be better to move it to the header, for the purpose of unit testing.

what's the point of putting functions and constants into the anonymous namespace, if it makes them unusable in tests?

To make them isolated from rest of the world. And it is not only functions and constants that you can put in the anonymous namespace - it is also for types.

However, if it makes your unit tests very complex, then you are doing it wrong. In such case the function doesn't belong there. Then it is time for a little refactoring to make the testing simpler.

So, in anonymous namespace should go only very simple functions, sometimes constants and types (including typedefs) used in that translation unit.

5

If you want to unit-test the private implementation-details, you do the same sort of dodge for unnamed namespaces as for private (or protected) class-members:

Break in and party.

While for classes you abuse friend, for unnamed namespaces you abuse the #include-mechanism, which doesn't even force you to change the code.
Now that your test-code (or better only something to expose everything) is in the same TU, there's no problem.

A word of caution: If you test the implementation-details, your test will break if those change. Be really sure to only test those implementation-details which will leak anyway, or accept that your test is unusually ephemeral.

5

It would be perfectly logical to write a separate unit test for match, because it's quite non-trivial.

The code you showed for match is a pretty trivial 1-liner without any tricky edge cases, or is that like a simplified example? Anyway, I'll assume it's simplified...

Question: what's the point of putting functions and constants into the anonymous namespace, if it makes them unusable in tests?

This question is what wanted to make me jump in here since Deduplicator already showed a perfectly good way to break in and get access through #include trickery. But the wording here makes it sounds like testing every single internal implementation detail of everything is some kind of universal end goal, when it's far from it.

The goal of even unit testing isn't always to test every little granular internal micro-unit of functionality. The same question applies to static file-scope functions in C. You can even make the question harder to answer by asking why developers use pimpls in C++ which would require both friendship and #include trickery to white box, trading easy testability of implementation details for improved compilation times, e.g.

From a kind of pragmatic perspective, it might sound gross but match may not be correctly implemented with some edge cases that cause it to trip up. However, if the sole outer class, Foo, that has access to match cannot possibly use it in a way that encounters those edge cases, then it's rather irrelevant to the correctness of Foo that match has these edge cases that will never be encountered unless Foo changes, at which point the tests of Foo will fail and we'll know immediately.

A more obsessive mindset eager to test every single internal implementation detail (perhaps a mission-critical software, e.g.) might want to break in and party, but a lot of people don't necessarily think that's the best idea, as it would create the most brittle tests imaginable. YMMV. But I just wanted to address the wording of this question which makes it sound like this kind of uber-fine-grained-internal-detail-level testability should be an end goal, when even the most rigorous unit testing mindset might relax a bit here and avoid x-raying the internals of every class.

So why do people define functions in anonymous namespaces in C++ or as file-scope static functions with internal linkage in C, hidden from the outside world? And that's mainly it: to hide them from the outside world. That has a number of effects from reducing compile times to reducing complexity (what cannot be accessed elsewhere cannot cause problems elsewhere) and so forth. Probably testability of private/internal implementation details isn't the number one thing on people's minds when they do it over, say, reducing build times and hiding unnecessary complexity from the outside world.

  • I wish I could upvote this ten times. As a tangent related to mission critical, high assurance software, you are much more concerned with the correctness of details. This idiomatic-style for C++ is not suited for that. I would not use features of the language like anonymous namespaces or proxy-like patterns. I would control my boundary coarsely with [supported] user-space headers and [unsupported] developer space headers. – David Jun 11 '18 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.