1
public Slave(Player player) {
    this.party = new Party(0, null, null, null, this);
    Networker.getInstance().sendString("--commandtype=system--message=setupclient--name=" + player.getPlayerName());
    synchronized (this) {
        this.status = State.WAITING;
    }
}

I need to write a Test with JUnit 3, but i have no idea how to write one to the code above. Because this methode sends a String to somewhere. I always get a nullpointer exception. What can I do? Im going for max code coverage

  • 2
    Refactor the code to make it testable. Avoid singletons like the plague. Pass the networker as argument to the constructor. Use dependency injection and a mocking framework. Use JUnit 4. JUnit 3 is ooooold. – JB Nizet Aug 15 '14 at 22:27
  • There's nothing wrong with having singletons per say. The singleton accessor is the problem (CC @JBNizet ) – Philip Whitehouse Aug 15 '14 at 22:38
  • @PhilipWhitehouse: agreed. What I precisely meant by "singleton" was "the singleton pattern as described in the GoF book". A unique instance of a class, injected everywhere it's needed, is fine. – JB Nizet Aug 15 '14 at 22:39

2 Answers2

3

This class depends on the Networker instance. Your goal is to substitute this dependency in tests. There are several ways to do that:

  1. Use service locator
  2. User IoC
  3. Mock Networker.getInstance()

Service Locator

In this case Slave shouldn't know where to get instance of Networker. It should get instance from central registry of services. This means that you need to have ServiceLocator class which basically would store link to Networker instance and you can replace it in tests.

IoC pattern

This is somewhat similar to Service Locator because Slave doesn't know where to get instance of Networker. This dependency should be provided externally (aka injected) in this case via constructor like this:

public Slave(Player player, Networker networker) {
    // same as above but networker passed to method is used
}

In this case you can use another instance of networker (or mock or stub) specifically designed for your test.

Directly mock static call

Some mock frameworks allow mocking static methods. You can mock call to Networking.getInstance() so that you can check that call happened with correct parameters. This is however not recommended and I discourage you to use this approach. See also this and this

Community
  • 1
  • 1
Roman Konoval
  • 12,545
  • 2
  • 32
  • 46
0

The code Networker.getInstance() looks like you are using the singleton pattern. You are probably getting the null pointer exception because the Networker singleton has not been initialised. So Networker.getInstance() returns null, and your call to sendString fails.

It is difficult to say exactly without seeing more of the code, but it seems likely that there will be another static method in the Networker class that allows you to initialise the singleton. You could try calling that from your test case.

However, be careful that doing this doesn't result in your test sending real messages over the network!

In my experience using the singleton pattern often results in these kinds of problems when writing tests. For this reason I normally try to avoid using the singleton pattern.

You may consider trying to refactor the code to improve its design and allow you to substitute a test double for the Networker. Consider trying to replace the use of a singleton with dependency injection.

Community
  • 1
  • 1
lexicalscope
  • 6,370
  • 6
  • 34
  • 56