Mockito издевается над SecurityManager, выдавая исключение

Я пытаюсь издеваться над классом SecurityManager. Когда я запускаю следующий код, Mockito выдает исключение:

@After
public void tearDown()
{
    SecurityManager securityManagerMock = mock(SecurityManager.class);
    System.setSecurityManager(securityManagerMock);
}

Трассировка стека — это бесконечно повторяющиеся строки:

at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:42)
at $java.lang.SecurityManager$$EnhancerByMockitoWithCGLIB$$3ceafc0f.checkMemberAccess(<generated>)
at java.lang.Class.checkMemberAccess(Class.java:2157)
at java.lang.Class.getDeclaredField(Class.java:1879)
at org.mockito.internal.creation.cglib.CGLIBHacker.reflectOnCreateInfo(CGLIBHacker.java:44)
at org.mockito.internal.creation.cglib.CGLIBHacker.setMockitoNamingPolicy(CGLIBHacker.java:20)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:42)
at $java.lang.SecurityManager$$EnhancerByMockitoWithCGLIB$$3ceafc0f.checkMemberAccess(<generated>)
at java.lang.Class.checkMemberAccess(Class.java:2157)
at java.lang.Class.getDeclaredField(Class.java:1879)
at org.mockito.internal.creation.cglib.CGLIBHacker.reflectOnCreateInfo(CGLIBHacker.java:44)
at org.mockito.internal.creation.cglib.CGLIBHacker.setMockitoNamingPolicy(CGLIBHacker.java:20)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:42)
at $java.lang.SecurityManager$$EnhancerByMockitoWithCGLIB$$3ceafc0f.checkMemberAccess(<generated>)
at java.lang.Class.checkMemberAccess(Class.java:2157)
at java.lang.Class.getDeclaredField(Class.java:1879)
at org.mockito.internal.creation.cglib.CGLIBHacker.reflectOnCreateInfo(CGLIBHacker.java:44)
at org.mockito.internal.creation.cglib.CGLIBHacker.setMockitoNamingPolicy(CGLIBHacker.java:20)

Что я здесь делаю неправильно?


person LandonSchropp    schedule 19.02.2012    source источник
comment
У меня эта строка отлично работает в Mockito 1.9.0. Возможно, вы могли бы предоставить дополнительную информацию - какую версию Mockito вы используете и (что более важно) КАКОЕ ИСКЛЮЧЕНИЕ вы получаете?   -  person Dawood ibn Kareem    schedule 19.02.2012
comment
Извините, похоже, исключение исходит не оттуда, где я думал. Я обновляю свой вопрос сейчас.   -  person LandonSchropp    schedule 19.02.2012
comment
Я думаю, что здесь происходит то, что Mockito использует метод getDeclaredField в своем фиктивном методе, и, поскольку есть менеджер безопасности, вызывается метод checkMemberAccess, чтобы увидеть, может ли объект Mockito это сделать. Как я могу это исправить?   -  person LandonSchropp    schedule 19.02.2012
comment
Просто любопытно: почему вы устанавливаете менеджера безопасности на издевательский в tearDown?   -  person avandeursen    schedule 19.02.2012
comment
Я переопределяю checkExit, чтобы предотвратить выход приложения при закрытии JFrame. Я пытаюсь протестировать класс, который создает JFrame, и мне нужно было снести JFrame после каждого теста, поэтому Frame.getFrames() возвращал только один кадр, который я тестировал.   -  person LandonSchropp    schedule 19.02.2012


Ответы (2)


ПС! Вы также можете имитировать статический вызов метода getSecurityManager().

Имитация статического метода /MockitoUsage

Добавьте @PrepareForTest на уровне класса.

@PrepareForTest(System.class); // System.class contains static methods

Вызовите PowerMockito.mockStatic(), чтобы имитировать статический класс (используйте PowerMockito.mockStaticPartial(class, method) для имитации определенного метода):

PowerMockito.mockStatic(System.class);

Просто используйте Mockito.when() для настройки ваших ожиданий:

Mockito.when(System.getSecurityManager()).thenReturn(securityManagerMock);
person Lauri    schedule 19.02.2012
comment
Это намного проще, чем то, что я пытался сделать. Спасибо за помощь. - person LandonSchropp; 19.02.2012
comment
@Lauri, откуда берется securityManagerMock, где мы его инициализируем? - person Kasun Siyambalapitiya; 27.09.2017
comment
@Lauri Не могли бы вы рассмотреть вопрос [stackoverflow.com/questions/46445422/ - person Kasun Siyambalapitiya; 27.09.2017

Когда вы меняете SecurityManager, вы должны сбросить его до исходного SecurityManager после теста.

Для теста вы можете использовать библиотеку Системные правила. Установка и сброс менеджера безопасности — это всего две строчки кода с этим правилом.

@Rule
public ProvideSecurityManager provideSecurityManager
  = new ProvideSecurityManager(yourSecurityManager);

В вашем тесте используется yourSecurityManager, а вне теста используется исходный менеджер безопасности.

person Stefan Birkner    schedule 20.02.2012