Angenommen, Sie haben die folgende Klasse haben würden Sie Test mögen:Best Practice - ein Feld Einstellung ohne Setter in einem Unit-Test
public class SomeService {
public String someMethod(SomeEntity someEntity) {
return someEntity.getSomeProperty();
}
}
Die SomeEntity sieht wie folgt aus:
public class SomeEntity {
private String someProperty;
public getSomeProperty() {
return this.someProperty;
}
}
Die Behauptung Sie möchten Folgendes tun:
String result = someService.someMethod(someEntity);
assertThat(result).isEqualTo("someValue");
Wie können Sie diesen Test arbeiten lassen?
1) Fügen Sie einen Setter für 'someProperty' in der SomeEntity-Klasse hinzu. Ich denke nicht, dass dies eine gute Lösung ist, weil Sie den Produktionscode nicht ändern, damit Ihre Tests funktionieren.
2) Verwenden Sie ReflectionUtils, um den Wert dieses Felds festzulegen. Test würde wie folgt aussehen:
public class TestClass {
private SomeService someService;
@Test
public void testSomeProperty() {
SomeEntity someEntity = new SomeEntity();
ReflectionTestUtils.setField(someEntity, "someProperty", "someValue");
String result = someService.someMethod(someEntity);
assertThat(result).isEqualTo("someValue");
}
}
3) Sie eine innere Klasse in Ihrer Testklasse erstellen, die die SomeEntity-Klasse erweitert und fügen den Setter für dieses Feld. Damit dies jedoch funktioniert, müssen Sie auch die SomeEntity-Klasse ändern, da das Feld "geschützt" statt "privat" werden soll. Test-Klasse könnte wie folgt aussehen:
public class TestClass {
private SomeService someService;
@Test
public void testSomeProperty() {
SomeEntityWithSetters someEntity = new SomeEntityTestWithSetters();
someEntity.setSomeProperty("someValue");
String result = someService.someMethod(someEntity);
assertThat(result).isEqualTo("someValue");
}
public class SomeEntityWithSetters extends SomeEntity {
public setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
}
}
4) Sie verwenden Mockito zu Mock SomeEntity. Scheint in Ordnung, wenn Sie nur eine Eigenschaft in der Klasse vortäuschen müssen, aber was ist, wenn Sie wie 10 Eigenschaften nachmachen müssen. Der Test könnte wie folgt aussehen:
public class TestClass {
private SomeService someService;
@Test
public void testSomeProperty() {
SomeEntity someEntity = mock(SomeEntity.class);
when(someEntity.getSomeProperty()).thenReturn("someValue");
String result = someService.someMethod(someEntity);
assertThat(result).isEqualTo("someValue");
}
}
Wenn Klasse ClassToTest Doesent haben Konstruktor oder Setter .. Wie in prod sie bevölkern die Eigenschaft .. wieder mit Reflexion? –
und ich denke, mit dem Junit testen Sie tatsächlich SomeService-Methode und nicht Classtotest. Wenn dies der Fall ist, können Sie ClasstoTest nachmachen. und das Testen von ClasstoTest wird separat durchgeführt und es sollte kein Mocking verwendet werden –
In diesem Fall wurde die Eigenschaft von Hibernate festgelegt, es ist eine Datenbank Entity, Hibernate benötigt keine Setter dafür. – wvp