1

I am integrating an external library that declares a singleton, like this:

public class External : MonoBehaviour {
    public static External Instance { get {/*setup inner stuff*/} }

    public void Method1(int arg);
    ...
    public bool MethodN(): // N is large
}

I created a wrapper with an interface, so I can unit-test the rest of my code.

I am wondering if there is an easy way to test/validate that my wrapper is correctly wired, i.e. every method calls the wrapped method, forwarding the parameters and returning the result (if non-void). e.g.:

public class ApiWrapper : IExernalAPI {
    public void Method1(int arg) {
        External.Instance.Method1(arg);
    }
    ...
    public bool MethodN() {
        return External.Instance.MethodN();
    }
}

should this class be "unit"-tested? if so, how?

M R
  • 21
  • 2
  • 1
    Possible duplicate of [Where is the line between unit testing application logic and distrusting language constructs?](http://softwareengineering.stackexchange.com/questions/322909/where-is-the-line-between-unit-testing-application-logic-and-distrusting-languag) – gnat Mar 21 '17 at 11:27
  • @gnat I don't think it's a duplicate. In this case, there is a real possibility of him calling External.Method2 instead of External.Method1 if he typed it in wrong, and it's easy to make that mistake by copy-pasting. – Eternal21 Mar 21 '17 at 14:15
  • Why not just have the singleton class implement the interface? – Greg Burghardt Mar 21 '17 at 17:40
  • Are you working with an infinite budget? If you really need to test at that level, you may need a state machine diagram. Encapsulation will go out the window. – Frank Hileman Mar 22 '17 at 01:31
  • @GregBurghardt the singleton class is part of the external library. the interface is mine. – M R Mar 22 '17 at 11:39
  • @FrankHileman not infinite, that's why I asked for an "easy" way to validate. I have been bitten by similar things, in which the wrapper called the method on itself instead of the wrapped object and it caused infinite recursion on the android device it was running (tail-call optimized), causing it to silently hang without any stacktrace... – M R Mar 22 '17 at 11:45

2 Answers2

0

In my view the easiest way to test something like this would be to test if the wrapper does the same thing as the singleton. This might be very difficult to test if the singleton ends up carrying a lot of state, but knowing that a certain set of parameters would produce the same result if either the singleton is called directly or the wrapper is called.

What does seem concerning is the fact the interface you created merely serves as a wrapper which would make me question why having the interface would benefit at all (ignoring the fact that it does provide easier testing when you can mock the interface). I'd rather move from a simple wrapper to something that acts a little more like an adaptor. Your use-cases would likely be different than just calling each of the methods directly where in this case you can probably model your interactions with the singleton in such a way that it might be simpler to check that given certain set of parameters it will ensure that the correct output is returned instead of merely wanting to check that the correct methods were called.

On the other hand some more high-level integration test might serve a purpose in picking up if the wrapper is set up correctly, but it's a big game of give and take.

Cyberwiz
  • 41
  • 4
  • Hi, I created the wrapper interface specifically for mocking the external service. as it's a networked sdk, it can't be mocked or simulated, each call is real (and it requires at least 2 connected clients to work properly). I ended up not testing the wrapper. – M R Jun 21 '17 at 08:38
0

The reason that you are creating this wrapper (being unable to stub the singleton) is the very reason that you cannot easily test the wrapper itself in isolation.

For a trivial wrapper like this a code review is a suitable alternative to an automated test. Any mistakes are easily spotted and the only reason for change (and consequently having to do another review) is a change in the interface of the singleton.

If N or the frequency of singleton interface changes is very large, you can also consider writing a generator to generate the wrapper from the singleton interface. You would have to compare the effort estimate and output quality for the generator vs that of code reviews to see which option makes most sense.

So in short: no, instead of unit-testing the wrapper, either generate it or rely on code reviews.

Griffon26
  • 36
  • 1