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):
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):
Een andere mogelijkheid zou een SocketFactory o.i.d. zijn, maar is dat niet wat overdreven? Wat zijn best-practises in dit soort gevallen?
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?
...