【问题标题】:Mockito Test - SimpMessageHeaderAccessor cannot be returned by getHeaders() getHeaders() should return MessageHeadersMockito 测试 - getHeaders() 不能返回 SimpMessageHeaderAccessor getHeaders() 应该返回 MessageHeaders
【发布时间】:2019-01-18 11:48:20
【问题描述】:

如何编写单元测试,因为它包括内部调用其他方法。

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是MessageHeaderAccessor类的静态方法

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

这是我的测试用例:

@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);
}

发生错误:

getHeaders() 无法返回 SimpMessageHeaderAccessor getHeaders() 应该返回 MessageHeaders 如果您不确定为什么会出现上述错误,请继续阅读。因为 可能会出现上述问题的语法性质,因为: 1. 此异常可能发生在错误编写的多线程测试中。请参阅 Mockito 常见问题解答以了解并发限制 测试。 2. 使用 when(spy.foo()).then() 语法对 spy 进行存根。存根间谍更安全- - 使用 doReturn|Throw() 系列方法。更多关于 Mockito.spy() 方法的 javadocs。

Message是一个接口,我mock它是一个实例,但是它根本无法获取headers,它是一个mock...我该如何解决这个问题..

【问题讨论】:

  • SimpMessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class) 返回什么?是不是在嘲讽?你想存根 POJO 吗?

标签: java spring unit-testing testing mockito


【解决方案1】:

你不能用 vanilla mockito 模拟静态方法。

我建议在 MyService 中创建一个受保护的方法来包装静态调用,然后模拟它:

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);
    }

然后在测试中:

@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));

      ....
}

这里的变化是你需要 Spy on MyService 才能模拟受保护的方法。

【讨论】:

  • Macjej,我搞错了,我只是改了代码 SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class);应该是 SimpMessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class);
  • 好的,那你试过了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
相关资源
最近更新 更多