代码之家  ›  专栏  ›  技术社区  ›  Jerry

Kotlin测试的UnfinishedSubbingException

  •  0
  • Jerry  · 技术社区  · 7 年前

    我正在转换一些 Java 代码到 Kotlin 我得到了一个 UnfinishedStubbingException 以下代码例外:

    @RunWith(SpringRunner::class)
    @SpringBootTest(classes = [FormsApplication::class])
    class AccountResourceIntTest {
    
        @Autowired
        lateinit var userRepository: UserRepository
    
        @Autowired
        lateinit var authorityRepository: AuthorityRepository
    
        @Autowired
        lateinit var userService: UserService
    
        @Autowired
        lateinit var passwordEncoder: PasswordEncoder
    
        @Autowired
        lateinit var httpMessageConverters: Array<HttpMessageConverter<*>>
    
        @Autowired
        lateinit var exceptionTranslator: ExceptionTranslator
    
        @Mock
        lateinit var mockUserService: UserService
    
        @Mock
        lateinit var mockMailService: MailService
    
        private lateinit var restMvc: MockMvc
    
        private lateinit var restUserMockMvc: MockMvc
    
    
        @Before
        fun setup() {
            MockitoAnnotations.initMocks(this)
            doNothing().`when`(mockMailService).sendActivationEmail(any()) <-- exception
            ...
        }
        ...
    }
    

    堆栈跟踪:

    org.mockito.exceptions.misusing.UnfinishedStubbingException: 
    Unfinished stubbing detected here:
    -> at com.application.web.rest.AccountResourceIntTest.setup(AccountResourceIntTest.kt:82)
    
    E.g. thenReturn() may be missing.
    Examples of correct stubbing:
        when(mock.isOk()).thenReturn(true);
        when(mock.isOk()).thenThrow(exception);
        doThrow(exception).when(mock).someVoidMethod();
    Hints:
     1. missing thenReturn()
     2. you are trying to stub a final method, which is not supported
     3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
    
        at com.application.service.UserServiceIntTest.init(UserServiceIntTest.kt:64)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        ...
    

    这个 MailService class 标记为 open .

    @Service
    open class MailService {
        ...
        @Async
        fun sendActivationEmail(user: User) {
            log.debug("Sending activation email to '{}'", user.email)
            sendEmailFromTemplate(user, "mail/activationEmail", "email.activation.title")
        }
    }
    

    这个 爪哇 代码我正在将此测试转换为:

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        doNothing().when(mockMailService).sendActivationEmail(any());
        ...
    }
    

    错误指向丢失的 thenReturn 声明,但原件中不要求这样做 爪哇 代码。这是怎么回事?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Jerry    7 年前

    通过将以下代码添加到 AccountResourceIntTest

    private fun <T> any(): T {
        Mockito.any<T>()
        return uninitialized()
    }
    private fun <T> uninitialized(): T = null as T
    

    对问题的解释以及如何解决发现的问题 here .