Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify with timeout not working after version 1.13.7 #1169

Open
3 tasks done
robpvn opened this issue Sep 26, 2023 · 1 comment · May be fixed by #1185
Open
3 tasks done

Verify with timeout not working after version 1.13.7 #1169

robpvn opened this issue Sep 26, 2023 · 1 comment · May be fixed by #1185

Comments

@robpvn
Copy link

robpvn commented Sep 26, 2023

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Expected Behavior

I would expect verify(timeout) to continue to work like it did before 1.13.7, so that CapturingSlots can capture values added from coroutines. Previously our tests worked as expected.

Current Behavior

Verify (timeout) does not seem to be waiting for the timeout, so tests are becoming flaky because of race conditions in the test code. About a third of the time the test will fail because the CapturingSlot has not yet captured the value we are checking for.

If we add a thread.sleep(250) before the call to verify, the test will not fail.

The problem started in version 1.13.7 and is still present in version 1.13.8.

Failure Information (for bugs)

This might be related to the change in #1099, like is mentioned in #1133 ? If the mock is cleared before the timeout check is done, or possibly during the timeout wait loop, the timeout could be instant.

Below is a minimal reproduction of the conditions that cause the issue.

// -----------------------[ YOUR STACK STARTS HERE ] -----------------------

kotlin.UninitializedPropertyAccessException: lateinit property captured has not been initialized
at io.mockk.CapturingSlot.getCaptured(API.kt:2626)

// -----------------------[ YOUR STACK TRACE ENDS HERE ] -----------------------
    private val logbackLogger: OurLogger = mockk()
    private lateinit var logStringSlot: CapturingSlot<String>

    @BeforeEach
    fun setUp() {
        logStringSlot = slot<String>()
        every { logbackLogger.log(capture(logStringSlot)) } returns Unit
        ReflectionTestUtils.setField(backingService, "logbackLogger", logbackLogger)
    }
    
    @Test
    fun `Log request`() {

        val request = createRequest()
        trackingService.trackRequest(request)
        
        //Adding a thread.sleep(250) here will work around the issue

        verify(timeout = 5000) { logbackLogger.log(any()) }

	//Fails around 1/3 of the time with kotlin.UninitializedPropertyAccessException: lateinit property captured has not been initialized
        val captured = logStringSlot.captured
        assertThat(captured)
            .and("info")
            .areIdentical()
    }
    
    
    fun trackRequest(queryRequest: QueryRequest) {
        val errorHandler = coroutineExceptionHandler()

        CoroutineScope(MDCContext())
            .launch(Job() + Dispatchers.IO + errorHandler) {
 
 		//Does stuff
 		
               backingService.log("info")
                
            }
    }
dsame added a commit to s4ysolutions/mockk that referenced this issue Nov 21, 2023
this is addressed to fix mockk#1169
@dsame dsame linked a pull request Nov 21, 2023 that will close this issue
@ajax-andrusenko-v
Copy link

Reproducible on 1.13.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants