HungryBird
HungryBird

Reputation: 1147

Mockito Test - SimpMessageHeaderAccessor cannot be returned by getHeaders() getHeaders() should return MessageHeaders

How to write the unit test, because it including the internal call other method.

public class MyService implements UserDestinationResolver {

    @Override
    public UserDestinationResult myMethod(Message<?> message){
    SimpMessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class);

****some logics to use access to get the return value UserDestinationResult***

    return UserDestinationResult;

getAccessor here is a static method from MessageHeaderAccessor class

@Nullable
public static <T extends MessageHeaderAccessor> T getAccessor(Message<?> message, Class<T> requiredType) {
        return getAccessor(message.getHeaders(), requiredType);
    } 

here is my test case:

@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {

    @Mock
    private Message<?> message;

    private SimpMessageHeaderAccessor accessor;

    @Mock
    private UserDestinationResult userDestinationResult;

    @InjectMocks
    private MyService myService;

    @Before
    public void set_up(){
        accessor = SimpMessageHeaderAccessor.wrap(message);
    }

    @Test
    public void resolveDestination(){
    when(MessageHeaderAccessor.getAccessor(message,
                SimpMessageHeaderAccessor.class)).thenReturn(accessor);

    """""""""""""""""""""""""""""""
    assertEquals(excepted, actual);
}

an Error occurs:

SimpMessageHeaderAccessor cannot be returned by getHeaders() getHeaders() should return MessageHeaders If you're unsure why you're getting above error read on. Due to the nature of the syntax above problem might occur because: 1. This exception might occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing. 2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

Message is a interface, I mock it as a instance, but it cannot get the headers at all, it is a mock...how can I solve this problem..

Upvotes: 0

Views: 763

Answers (1)

Maciej Kowalski
Maciej Kowalski

Reputation: 26572

You cannot mock a static method with vanilla mockito.

I would suggest creating a protected method in MyService which would wrap the static call, and then mock it:

public class MyService implements UserDestinationResolver {

    @Override
    public UserDestinationResult myMethod(Message<?> message){
    SimpMessageHeaderAccessor accessor = getAccessor(message, SimpMessageHeaderAccessor.class);
     ...
    }

    protected SimpMessageHeaderAccessor getAccessor(Message<?> message, Class<T> requiredType){
         return SimpMessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class);
    }

Then in test:

@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {

    @Mock
    private Message<?> message;


    @Mock
    private UserDestinationResult userDestinationResult;

    @InjectMocks
    @Spy
    private MyService myService;

    @Before
    public void set_up(){
        accessor = SimpMessageHeaderAccessor.wrap(message);
    }

    @Test
    public void resolveDestination(){
       // Arrange
       doREturn(accessor).when(myService).getAccessor(message,
                SimpMessageHeaderAccessor.class));

      ....
}

The change here is that you need to Spy on MyService to be able to mock the protected method.

Upvotes: 1

Related Questions