[java] Best-practise bij de-coupling Socket

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 09:25
Ik ben bezig met het ontwikkelen van een applicatie, en ik loop een beetje vast bij het implementeren van een klasse die een paar kleine berichten moet sturen over een socket. Ik probeer alles zo goed mogelijk los te koppelen van elkaar, zodat ik alle onderdelen afzonderlijk kan unittesten en gebruik kan maken van dependency injection / mocks.

De verbinding naar de server heb ik gewrapped in een Connection class die er grof gezegd ongeveer zo uitziet (heb hier alle overige code weggelaten):

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Connection {
    private String host;
    private int port;
    private Socket socket;
    private BufferedWriter writer;
    private BufferedReader reader;
    
    public Connection(String host, int port) {
        this.host = host;
        this.port = port;
    }
    
    public void open() throws UnknownHostException, IOException {
        //....//
        this.socket = new Socket(host, port);
        this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //....//
    }
    
    public void close() throws IOException {
        //....//
        this.reader.close();
        this.writer.close();
        this.socket.close();
        //....//
    }
}


De Connection zelf is prima te mocken in een klasse welke gebruik maakt van een Connection, alleen de Connection klasse zelf is zo niet te unittesten. Hiervoor zal ik de Socket moeten mocken. Ik heb dit nu opgelost door een protected methode createSocket() toe te voegen die de socket aanmaakt en teruggeeft zodat ik deze in een unit test kan overriden (zie voorbeeld), maar ik vraag me af of dat wel de juiste manier is.

In de unit test van Connection doe ik dus zoiets (uiteraard krijg ik zo nooit een 100% test coverage maar dat is ook geen doel opzich lijkt me):
Java:
1
2
3
4
5
6
conn = new Connection("localhost", 100) {
    @Override
    protected Socket createSocket() {
        return socketMock;
    }
};


Een andere mogelijkheid zou een SocketFactory o.i.d. zijn, maar is dat niet wat overdreven? Wat zijn best-practises in dit soort gevallen?

...


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Je kan toch ook gewoon in je unit-tests een socket listener (geen idee wat dat is in java) openen en daar je Connection class naartoe laten connecten?
Ik neem aan dat je in je unit tests wilt gaan testen of je klasse de juiste data verstuurd?

Lijkt me een stuk eenvoudiger dan een Socket gaan mocken. Geen idee of het best-practice is, maar zo zou ik het doen.

[ Voor 5% gewijzigd door TheNameless op 22-01-2013 16:22 ]

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 09:25
Het liefst zou ik niet met een echte socket werken. Zowel bij het opzetten van een listener, als het openen van een socket kan er vanalles mis gaan (firewall bijvoorbeeld waardoor het niet werkt) waardoor mijn test faalt terwijl er niets mis is met de code.

Een socket mocken is overigens niets meer als:

Java:
1
2
@Mock
private Socket socketMock


in mijn test (ik gebruik mockito).

[ Voor 22% gewijzigd door IceM op 22-01-2013 16:30 ]

...