views:

38

answers:

1

I'm relatively new to unit testing, and trying it on my personal projects. I want to unit test some concurrent methods (futures which run actions in the thread pool). To avoid the test method finishing before the thread pooled action, I'm blocking the test. Here is the actual blocking code:

Private Shared Function BlockOnFuture(ByVal future As IFuture,
                                      ByVal timeout As TimeSpan) As Boolean
    Dim waitHandle = New System.Threading.ManualResetEvent(initialState:=False)
    AddHandler future.Ready, Sub() waitHandle.Set()
    If future.State <> FutureState.Unknown Then waitHandle.Set() 'already ready'
    Return waitHandle.WaitOne(timeout)
End Function
Private Shared Function BlockOnFuture(ByVal future As IFuture) As Boolean
    Return BlockOnFuture(future, New TimeSpan(0, 0, seconds:=5))
End Function

I have tests which intentionally don't set a future, for example:

<TestMethod()>
Public Sub CallWhenReady_Dangle()
    Dim flag = True
    Dim future = New FutureAction() 'A class which has methods to make it become ready'
    Dim result = future.CallWhenReady(Sub(exception)
                                          flag = False
                                      End Sub)
    'should fail, because the future action is not being set'
    Assert.IsFalse(BlockOnFuture(result))
    'future was not set so the action did not run'
    Assert.IsTrue(flag) 
    'action did not run so the result should not be set either'
    Assert.IsTrue(result.State = FutureState.Unknown)
End Sub

I think Visual studio runs the tests one by one, because every test waits patiently while this one takes 5 seconds to timeout and complete. Is there a way I can force certain tests to run concurrently? Am I approaching this wrong?

A: 

It's been a long day but I think my advice would be the approach is wrong. Really you want to stub out the future behavior.

A kluge would be to modify the default test timeout. You can do this with an attribute I think (most test Fx let you do this but I can't remember the syntax for MSTest which appears to b the one you're using).

Ade Miller
How will stubbing help? In this test the 'input' future literally does nothing, and I check that the future returned from the method has also done nothing. Also, I am setting the timeout as part of the test. it is not part of MSTest.
Strilanc