I'm writing a unit test suite to test a TCP/IP communication library.
As I'm using BeginAcceptClient and EndAcceptClient, the messages are received in a background thread.
After a message is received, I perform some assertions on it, but if any assertion fails, the VSTestHost.exe crashes.
I googled a bit and found out its the fact the Assert exceptions are being thrown in a background thread.
EDIT: A sample code of what I am doing, just to ilustrate:
public void TestFooMessage() {
Server.OnReceive += (s, e) => {
Assert.IsInstanceOfType(e.Message, typeof(Foo));
};
var message = new Foo();
Client.Send(message);
}
Does anyone know how to make it work as expected: Log the assertion and continues running normally?
You should not write the Asserts in the background thread (say: the background event handler), because the test framework can not handle this. You should only gather values there. You can synchronize the main thread for instance using AutoResetEvents. Write the values into fields, assert the fields in the main thread.
If the messages are never coming in, you need a timeout.
A bit pseudo code (actually not that pseudo):
private AutoResetEvent ReceiveEvent = new AutoResetEvent(false);
private EventArgs args;
private bool ReceiveCalled = false;
// event handler with some argument
private void Receive(object sender, EventArgs args)
{
// get some arguments from the system under test
this.args= args;
// set the boolean that the message came in
ReceiveCalled = true;
// let the main thread proceed
ReceiveEvent.Set();
}
[TestMethod]
public void Test()
{
// register handler
Server.OnReceive += Receive;
var message = new Foo();
Client.Send(message);
// wait one second for the messages to come in
ReceiveEvent.WaitOne(1000);
// check if the message has been received
Assert.IsTrue(
ReceiveCalled,
"AcceptClientReceived has not been called");
// assert values from the message
Assert.IsInstanceOfType(args.Message, typeof(Foo))
}
By the way: you still can write the handler as a lambda expression and even avoid the fields by using local variables. But it could be harder to read if everything is in a single method.
I suspect you'll basically need some sort of "everything okay" flag:
Assert
method which clears the flag and maybe sets another variable for the "reason" (or adds it to a list) then exits the thread cleanly (if possible)It's possible that some test frameworks have this built in, but I don't know of any offhand...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With