Прежде всего, позвольте мне сказать громче, вам нужно спроектировать свой код так, чтобы он был тестируемым, чтобы вы тестировали свои личные поля с помощью открытых методов.
Но («но» — это причины, по которым люди все еще программируют, а не сам компьютер, так что будьте счастливы здесь), иногда вы хотите и должны изменить некоторые частные поля, чтобы проверить все возможные границы.
Часто закрытые поля можно изменить с помощью общедоступных методов получения и установки или с помощью конструктора классов, и в этих случаях тесты легко создавать, и все довольны.
Но когда вы используете внешние фреймворки, такие как Spring, может оказаться, что вы не можете контролировать внедренные приватные поля.
Я уже объяснял, как макетировать компоненты пружин в ваших тестах без необходимости поддержки и создания специальных конфигураций тестовых пружин в предыдущем посте, здесь я покажу вам, как изменить частную переменную для ваших тестов.
Пусть говорят код:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import com.google.common.collect.ImmutableSet;@Servicepublic class SomeService { @Value("${whitelist.api.users:A,B,C}") private String apiUsers; private ImmutableSet<String> acceptableAPIBUsers; @PostConstruct public void init() { acceptableAPIBUsers = ImmutableSet.copyOf(apiUsers.replaceAll(" ", "").split(",")); } public boolean isAnAcceptableUser(String user) { return user == null ? false : acceptableAPIBUsers.contains(user.toUpperCase()); }} |
У нас нет контроля над строкой apiUsers, поэтому у нас есть несколько простых опций, одна из которых — создать конфигурацию Spring для вашего теста, изменить контекст Spring и смоделировать свойство, а вторая — создать установщик для изменения значения собственность из вашего теста.
Я не рекомендую создавать общедоступные оценщики только для ваших тестов, так как это может сбивать с толку других людей, которые смотрят на ваш код, и создание и поддержка конфигураций Spring для ваших тестов может быть трудной задачей.
Я знаю, что вы думаете: «Если я не смогу сделать что-либо из вышеперечисленного, меня уволят, моя девушка бросит меня, и моя жизнь закончится», но не беспокойтесь, я здесь, чтобы показать вам другой вариант!
Вы можете создать класс с классическим методом для оценки вашего личного поля в тесте:
|
1
2
3
4
5
6
7
8
|
import groovy.transform.CompileStatic@CompileStaticclass SomeServiceAccessor { public static void setApiUsers(SomeService someService,String apiUsers){ someService.@apiUsers = apiUsers }} |
И используйте его в своем модульном тесте:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
import static org.hamcrest.CoreMatchers.is;import static org.junit.Assert.assertThat;import org.junit.Before;import org.junit.Test;public class SomeServiceTest { private SomeService service; @Before public void setUp() { service = new SomeSercvice(); SomeSercviceAccessor.setApiUsers(service, "pippo,pluto,bungabunga"); service.init(); } @Test public void testIsNotApiUser() { assertThat(service.isAnRTBUser(""), is(false)); assertThat(service.isAnRTBUser(null), is(false)); assertThat(service.isAnRTBUser("random"), is(false)); } @Test public void testIsRTBUser() { assertThat(service.isAnRTBUser("pippo"), is(true)); assertThat(service.isAnRTBUser("PIPPO"), is(true)); assertThat(service.isAnRTBUser("pluto"), is(true)); assertThat(service.isAnRTBUser("bungabunga"), is(true)); }} |
Конечно, вы можете сделать то же самое в java, изменив видимость поля с помощью отражения, но я думаю, что отличное решение может быть чище и проще.
Теперь я закончу этот пост следующей рекомендацией:
Не используйте это решение, если вам действительно не нужно изменять частные переменные для модульного тестирования вашего класса!
