Hi Wang Peng,
I fully agree with the advices given to you by others on this list. If
you really need to mock those static functions, they belong in a
separate module, where they serve as that module's API.
If you found out that your static functions are in fact "harmful", you
could try to refactor the harmfulness out of them, without moving them
from their current location.
I interpret "harmful" as having communication (I/O) with an external
entity, without allowing the client to control what this external entity
is. The issue also concerns input like reading files, the system clock,
or a random number generator. Anything that makes the function have
unavoidable side-effects or non-deterministic behavior.
For instance, the following function is "harmful":
int harmful(const char * name)
{
return fprintf(stdout, "Hello %s\n", name);
}
while this one is not:
int harmless(FILE * stream, const char * name)
{
return fprintf(stream, "Hello %s\n", name);
}
The function harmful() is hard-wired to "stdout". Breaking this wiring
requires tricks like link-stubbing fprintf(), assigning "stdout" to
something else, or maybe doing symbol replacement with the preprocessor.
Otherwise, this function _will_ print its stuff to your terminal when
being tested, and you will have to redirect "stdout" to somewhere else,
on the outside of your test-process, to pick up the printed string and
check that harmful() behaved correctly.
On the other hand, harmless() lets the client determine where to send
the output. Your production code will pass "stdout" as argument, while
your tests pass some alternative mock FILE stream, e.g. one created by
fmemopen() or open_memstream(), which can then be inspected in-memory by
the test case after the call to harmless().
In my experience, software architecture quality goes up as the
percentage of harmful code goes down, due to increased modularity (less
coupling). Ultimately, your program contains only one harmful function,
main(), leaving all other code easily testable since it allows explicit
control over all its I/O collaborators.
In Haskell, the difference between harmful and harmless is considered so
important that it is built into the language itself. It is referred to
as "purity". The type-system ensures that pure (i.e. "harmless") code
cannot possibly call impure (i.e. "harmful") code. Personally, I have
never used Haskell for anything serious. However, I have found the
"purity" perspective to be very valuable and have brought it back with
me when I work on C/C++ code. It goes hand in hand with testability.
--
Thanks,
Knut Aksel R�ysland
On 08/02/2012 09:45 AM, Rex Wang wrote:
> Hi,
>
> I can't understand the 'harmful' exactly :-(
> but what if they do things harmful? what should I do for such conditions?
>
> Wang Peng
>
> On Thu, Aug 2, 2012 at 3:37 PM, Bas Vodde <
ba...@odd-e.com
> <mailto:
ba...@odd-e.com>> wrote:
>
>
> Hiya,
>
> > yes, actually, inside a module, those private functions are only
> used by the public ones inside that module.
> > but when testing those public ones, I want to mock those private
> functions to test each branch of the public ones.
> >
> > besides this, I think even in C++, the private functions still
> needs UT, so how is these UT work be done in the project written in
> C++? can you please give me some suggestions?
>
> Yes, usually you test them through the public interface :)
>
> In unit testing, usually you don't write one test for one method but
> for one "piece of functionality". Therefore, you usually access the
> private methods via the public interface. Therefore, usually you
> don't need to mock the private methods, unless they do something
> harmful�
>
> Do they do something harmful?
>
> Bas
>
> >
> > Wang Peng
> >
> > On Thu, Aug 2, 2012 at 3:19 PM, Bas Vodde <
ba...@odd-e.com
> <mailto:
ba...@odd-e.com>> wrote:
> >
> > Hi Wang Peng,
> >
> > Uhm, will you be able to access these private functions via the
> public ones?
> >
> > And� why would you want to mock out the static private functions?
> >
> > Thanks!
> >
> > Bas
> >
> > On 2 Aug, 2012, at 1:54 PM, Rex Wang <
nuyi...@gmail.com