4
    @PostMapping
        @ResponseStatus(HttpStatus.CREATED)
        @PreAuthorize("@messageSecurityService.isAuthorized(#userAuthentication)")
        public void sendMessage(@AuthenticationPrincipal UserAuthentication userAuthentication,
                                @RequestBody SendMessageRequest sendMessageRequest) {
                                              ......
     }

I want to write the test of this endpoint, but I am getting the following error.

 java.lang.IllegalArgumentException: Failed to evaluate expression '@messageSecurityService.isAuthorized(#userAuthentication)'
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30)
    at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:59)
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:72)
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:40)
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:63)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1058E: A problem occurred when trying to resolve bean 'messageSecurityService':'Could not resolve bean reference against BeanFactory'
    at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:59)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:53)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:89)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:300)
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:26)
    ... 94 common frames omitted

Caused by: org.springframework.expression.AccessException: Could not resolve bean reference against BeanFactory
    at org.springframework.context.expression.BeanFactoryResolver.resolve(BeanFactoryResolver.java:54)
    at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:55)
    ... 99 common frames omitted

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'messageSecurityService' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:775)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:273)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)
    at org.springframework.context.expression.BeanFactoryResolver.resolve(BeanFactoryResolver.java:51)
    ... 100 common frames omitted

How can I make the expression resolve bean ?

Using @MockBean MessageSecurityService didn't work.

1 Answers1

2

Have you stub the return of the @MockBean e.g

@MockBean(name = "messageSecurityService")
public MessageSecurityService messageSecurityService;

@Test
public void testing(){
 when(messageSecurityService.isAuthorized(anyString())).thenReturn("somethingHere");
 //rest of your assertions
}

also have you added the following in your test class:

@BeforeEach
public void init() {
    MockitoAnnotations.initMocks(this);
}
  • 1
    Yes thank you it worked. @MockBean (name = "message Security Service") that's enough to do that. Working without adding MockitoAnnotations.initMocks (this). – Serhat Yıldırım Oct 08 '20 at 17:28
  • We added the set-up method that initializes all of the mocked objects together when the test runs. The method annotated with @BeforeEach gets ran before each test method. The init() method runs MockitoAnnotations.initMocks(this) using this instance as the argument. This sets up our mocks before each test – Muhammad Arslan Akhtar Oct 09 '20 at 00:49
  • Since my test runs with SpringRunner, it sets up mocks, without the need for initMocks already doing this within itself. /** * Construct a new {@code SpringRunner} and initialize a * {@link org.springframework.test.context.TestContextManager TestContextManager} * to provide Spring testing functionality to standard JUnit 4 tests. – Serhat Yıldırım Oct 09 '20 at 06:35
  • Why does the mockbean annotation want the name bean as a parameter into it? The test did not work without writing Bean's name. – Serhat Yıldırım Oct 09 '20 at 06:48