首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mockito @MockBean不会在Kotlin上执行

Mockito @MockBean不会在Kotlin上执行
EN

Stack Overflow用户
提问于 2022-06-22 01:26:01
回答 1查看 159关注 0票数 0

我对Kotlin/Mockito问题感到非常沮丧

我想要完成的非常简单,我在我的springboot应用程序上有一个AuthorizationFilter,为了测试目的,我想模拟它的行为,让测试请求通过。

我的AuthorizationFilter确实调用了一个API,该API将提供用户auth状态。所以我想,最简单的模拟方法就是在过滤器中模拟AuthApi,然后返回我想要的状态.但它是随机工作的

代码语言:javascript
运行
复制
@Component
class AuthorizationFilter(
    val authApi: authApi
) : OncePerRequestFilter() {

    override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) {
        if (request.method.equals("OPTIONS")) {
            filterChain.doFilter(request, response)
            return
        }

        val token = request.getHeader("authorization")

        if (token == null) {
            response.sendError(401)
            return
        }


        runCatching {
            authApi.authorize(token.replace("Bearer ", ""))
        }.onSuccess {
            AuthorizationContext.set(it)
            filterChain.doFilter(request, response)
        }.onFailure {
            it.printStackTrace()
            response.sendError(401)
        }
    }
    
    }

authApi授权方法与这个问题无关,但是让我们知道它永远不会返回null.它可能会引发异常,但不会返回null

代码语言:javascript
运行
复制
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
class SocketIOServerTest {
    @MockBean
    lateinit var mockedApiComponent: AuthApi


    @Autowired
    lateinit var boardRepository: BoardRepository


    @Autowired
    private lateinit var servletRegistrationBean: ServletRegistrationBean<SocketIOServer>
    private lateinit var socketIOServer: SocketIOServer

    @LocalServerPort
    private val serverPort: String? = null

    lateinit var clientSocket: Socket

    private val userId = 1
    private val groupId = 123
    private val admin = false
    private val auth = Authorization("token", userId, groupId, admin)

    private val objectMapper = ObjectMapper()


    @BeforeAll
    fun connect() {
        AuthorizationContext.set(auth)
        Mockito.`when`(mockedApiComponent.authorize(anyOrNull())).thenReturn(auth)

        socketIOServer = servletRegistrationBean.servlet

        clientSocket = IO.socket("http://localhost:${serverPort}", IO.Options.builder().setExtraHeaders(mutableMapOf(Pair("Authorization", listOf("Bearer token")))).build())
        clientSocket.on(Socket.EVENT_CONNECT) {
            println("client connected")

        }
        clientSocket.on(Socket.EVENT_DISCONNECT) {
            println("client disconnected")
        }
        clientSocket.connect()
    }



    @Test
    fun testPingPong() {
        var finished = false
        clientSocket.on("pong") {
            println("event: ${it[0]}")
            val pongTime = (it[0] as String).substring(18, 31).toLong()
            assertTrue(System.currentTimeMillis() - pongTime < 1000)
            finished = true
        }
        clientSocket.emit("ping")

        while (!finished) Thread.yield()
    }

    @Test
    fun testBasicNotification(){

        clientSocket.on("basic_notification"){
            println(Arrays.toString(it))
        }

        socketIOServer.send(SocketIOEvent("${groupId}","basic_notification","data"))
        Thread.sleep(1000)
    }

    @Test
    fun testBoardNotification() {


        clientSocket.on("entity_create") {
            val event = it[0] as String
            println("event: $event")
            val eventValue = objectMapper.readValue(event, Map::class.java)
            val entityValue = eventValue["entity"] as Map<*, *>

            assertEquals("BOARD", eventValue["entity_type"])
            assertEquals("board name", entityValue["name"])
            assertEquals(groupId, entityValue["groupId"])

            assertEquals(userId, entityValue["created_by"])
            assertEquals(userId, entityValue["last_modified_by"])


        }

        val board = boardRepository.save(Board(groupId, "board name"))


        //boardRepository.delete(board)

    }}

要明确的是,测试是有效的,断言是正确的,虽然它在结尾有一些随机行为,但它起作用.但是由于一些疯狂的行为,它打印了一个很大的堆栈跟踪

如您所见,我使用的是一个SocketIO客户端,它从代码中发送几个请求.其中一些通过身份验证,还有一些在这一行中抛出nullpointerexception。

代码语言:javascript
运行
复制
.onSuccess {
                AuthorizationContext.set(it) //this line
                filterChain.doFilter(request, response)
            }.

因为it是空的,因为mockedApiComponent.authorize()以某种方式返回空.同样,这在实际组件上是不可能的,而且不应该发生,因为模拟清楚地声明要返回哪个对象。

我彻底地删除了这段代码,认为junit得到了AuthApi的两个bean,但是整个执行显示了与模拟匹配的相同的对象id .更奇怪的是,用于授权的token参数总是相同的。

有谁可以帮我?

EN

回答 1

Stack Overflow用户

发布于 2022-07-03 07:30:00

我已经彻底地删除了这段代码,我认为junit得到了AuthApi的两个bean,但是整个执行显示了与模拟匹配的相同的对象id .更奇怪的是,授权时使用的令牌参数总是相同的。

这在我看来是令人不安的,就像运行时异步代码的一些问题。我会尝试做几件事:

  1. 检查上下文何时为null:AuthorizationContext.set(it),并放置更多调试代码以了解发生了什么。或者只是从那里调试,
  2. 使用recover{}块来处理NullPointerException,从那里调试查看堆栈跟踪
  3. 中的原始问题当使用runCatching{}时会发生什么?
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72708712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档