Unit Test heartbeat functionality












2















I have a client-server system based on TCP coded in C#. I was requested to add a bidirectional heartbeat to discover if any of the elements in the network freeze and are not responding.



I solved the problem by sending a heartbeat from the server to all connected clients and waiting for the response. There's a timeout if the response doesn't come on time and there is a timeout in the clients if the server didn't send any heartbeat in 2 seconds (assuming the server is frozen).



Everything happens internally and the server nor the client expose any of the events (receiving a heartbeat, replying a heartbeat happen silently, as it was requested)



The thing is .. How does one create a unit test or integration test for such a functionality?



Note: I'm coding in visual studio, C#, .Net 4.6.1, testing using NUnit3



Brief pseudocode example:



//we have one connector for each connected client
class connector{

//if the echoReceived timer is not reseted on time it will complain
Timer echoReceived = new Timer(200ms);
//Another timer for sending beats
Timer heartbeatSender = new Timer (1000ms);

OnClientConnected(Client)
{
echoReceived.elapsed += () => { ShowError("Client did not reply") };

heartbeatSender.elapsed += () => {
Send(client, new Message(Heartbeat));
echoReceived.Enabled = true;
});
heartbeatSemder.isEnabled = true;
}

OnNewMessageFromClient(Client, message)
{
if(message is echoedHeartBeat)
{
echoReceived.Enabled= false;
echoReceived.Reset();
}
}

}


On the client side



class client 
{
Timer ServerDeadTimeOut = new Timer (1000ms);

OnStart()
{
serverDeadTimeOut.Elapsed += () => { ShowError("Server is dead"); };
serverDeadTimeOut.isEnabled = true;
}

OnNewMessageFromServer(message)
{
if(message is HeartBeatMessage)
{
serverDeadTimeOut.Reset();
Send(new HeartBeatEchoMessage);
}
}
}









share|improve this question

























  • abstract out implementation concerns that would allow more flexibility testing expected behavior.

    – Nkosi
    Nov 27 '18 at 16:26
















2















I have a client-server system based on TCP coded in C#. I was requested to add a bidirectional heartbeat to discover if any of the elements in the network freeze and are not responding.



I solved the problem by sending a heartbeat from the server to all connected clients and waiting for the response. There's a timeout if the response doesn't come on time and there is a timeout in the clients if the server didn't send any heartbeat in 2 seconds (assuming the server is frozen).



Everything happens internally and the server nor the client expose any of the events (receiving a heartbeat, replying a heartbeat happen silently, as it was requested)



The thing is .. How does one create a unit test or integration test for such a functionality?



Note: I'm coding in visual studio, C#, .Net 4.6.1, testing using NUnit3



Brief pseudocode example:



//we have one connector for each connected client
class connector{

//if the echoReceived timer is not reseted on time it will complain
Timer echoReceived = new Timer(200ms);
//Another timer for sending beats
Timer heartbeatSender = new Timer (1000ms);

OnClientConnected(Client)
{
echoReceived.elapsed += () => { ShowError("Client did not reply") };

heartbeatSender.elapsed += () => {
Send(client, new Message(Heartbeat));
echoReceived.Enabled = true;
});
heartbeatSemder.isEnabled = true;
}

OnNewMessageFromClient(Client, message)
{
if(message is echoedHeartBeat)
{
echoReceived.Enabled= false;
echoReceived.Reset();
}
}

}


On the client side



class client 
{
Timer ServerDeadTimeOut = new Timer (1000ms);

OnStart()
{
serverDeadTimeOut.Elapsed += () => { ShowError("Server is dead"); };
serverDeadTimeOut.isEnabled = true;
}

OnNewMessageFromServer(message)
{
if(message is HeartBeatMessage)
{
serverDeadTimeOut.Reset();
Send(new HeartBeatEchoMessage);
}
}
}









share|improve this question

























  • abstract out implementation concerns that would allow more flexibility testing expected behavior.

    – Nkosi
    Nov 27 '18 at 16:26














2












2








2


1






I have a client-server system based on TCP coded in C#. I was requested to add a bidirectional heartbeat to discover if any of the elements in the network freeze and are not responding.



I solved the problem by sending a heartbeat from the server to all connected clients and waiting for the response. There's a timeout if the response doesn't come on time and there is a timeout in the clients if the server didn't send any heartbeat in 2 seconds (assuming the server is frozen).



Everything happens internally and the server nor the client expose any of the events (receiving a heartbeat, replying a heartbeat happen silently, as it was requested)



The thing is .. How does one create a unit test or integration test for such a functionality?



Note: I'm coding in visual studio, C#, .Net 4.6.1, testing using NUnit3



Brief pseudocode example:



//we have one connector for each connected client
class connector{

//if the echoReceived timer is not reseted on time it will complain
Timer echoReceived = new Timer(200ms);
//Another timer for sending beats
Timer heartbeatSender = new Timer (1000ms);

OnClientConnected(Client)
{
echoReceived.elapsed += () => { ShowError("Client did not reply") };

heartbeatSender.elapsed += () => {
Send(client, new Message(Heartbeat));
echoReceived.Enabled = true;
});
heartbeatSemder.isEnabled = true;
}

OnNewMessageFromClient(Client, message)
{
if(message is echoedHeartBeat)
{
echoReceived.Enabled= false;
echoReceived.Reset();
}
}

}


On the client side



class client 
{
Timer ServerDeadTimeOut = new Timer (1000ms);

OnStart()
{
serverDeadTimeOut.Elapsed += () => { ShowError("Server is dead"); };
serverDeadTimeOut.isEnabled = true;
}

OnNewMessageFromServer(message)
{
if(message is HeartBeatMessage)
{
serverDeadTimeOut.Reset();
Send(new HeartBeatEchoMessage);
}
}
}









share|improve this question
















I have a client-server system based on TCP coded in C#. I was requested to add a bidirectional heartbeat to discover if any of the elements in the network freeze and are not responding.



I solved the problem by sending a heartbeat from the server to all connected clients and waiting for the response. There's a timeout if the response doesn't come on time and there is a timeout in the clients if the server didn't send any heartbeat in 2 seconds (assuming the server is frozen).



Everything happens internally and the server nor the client expose any of the events (receiving a heartbeat, replying a heartbeat happen silently, as it was requested)



The thing is .. How does one create a unit test or integration test for such a functionality?



Note: I'm coding in visual studio, C#, .Net 4.6.1, testing using NUnit3



Brief pseudocode example:



//we have one connector for each connected client
class connector{

//if the echoReceived timer is not reseted on time it will complain
Timer echoReceived = new Timer(200ms);
//Another timer for sending beats
Timer heartbeatSender = new Timer (1000ms);

OnClientConnected(Client)
{
echoReceived.elapsed += () => { ShowError("Client did not reply") };

heartbeatSender.elapsed += () => {
Send(client, new Message(Heartbeat));
echoReceived.Enabled = true;
});
heartbeatSemder.isEnabled = true;
}

OnNewMessageFromClient(Client, message)
{
if(message is echoedHeartBeat)
{
echoReceived.Enabled= false;
echoReceived.Reset();
}
}

}


On the client side



class client 
{
Timer ServerDeadTimeOut = new Timer (1000ms);

OnStart()
{
serverDeadTimeOut.Elapsed += () => { ShowError("Server is dead"); };
serverDeadTimeOut.isEnabled = true;
}

OnNewMessageFromServer(message)
{
if(message is HeartBeatMessage)
{
serverDeadTimeOut.Reset();
Send(new HeartBeatEchoMessage);
}
}
}






c# unit-testing nunit client-server integration-testing






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 27 '18 at 16:00









W.Ambrozic

901212




901212










asked Nov 16 '18 at 8:29









javirsjavirs

562734




562734













  • abstract out implementation concerns that would allow more flexibility testing expected behavior.

    – Nkosi
    Nov 27 '18 at 16:26



















  • abstract out implementation concerns that would allow more flexibility testing expected behavior.

    – Nkosi
    Nov 27 '18 at 16:26

















abstract out implementation concerns that would allow more flexibility testing expected behavior.

– Nkosi
Nov 27 '18 at 16:26





abstract out implementation concerns that would allow more flexibility testing expected behavior.

– Nkosi
Nov 27 '18 at 16:26












2 Answers
2






active

oldest

votes


















3





+25









I'd go for Unit Tests, integration would require setting up some kind of connection between these two, depending on implementation it can be easier or harder. Unit Tests would simply rely on the abstraction. Just inject interfaces to the Connector and for unit testing replace them with Mocks to simulate scenarios that you designed that class for. Of course then you have to test actual implementations of Timer, Logger and ClientListener, but that's what unit tests are for.



public class ConnectorTest
{
private readonly Connector _connector;
private readonly TimerMock _receiverMock;
private readonly TimerMock _senderMock;
private readonly LoggerMock _loggerMock;
private readonly ClientListenerMock _listenerMock;

public void Setup()
{
_listenerMock = new ClientListenerMock();
_receiverMock = new TimerMock();
_senderMock = new TimerMock();
_loggerMock = new LoggerMock();
_connector = new Connector(_listenerMock, _receiverMock, _senderMock, _loggerMock)
}

public void HeartbeatSender_ShouldBeEnabled_OnceClientIsConnected()
{
_listenerMock.SimulateClientConnection();

Assert.IsTrue(_senderMock.IsEnabled);
}

public void Error_ShouldBeLogged_WhenConnectedClientDidNotEchoed()
{
_listenerMock.SimulateClientConnection();

_receiverMock.SimulateEchoTimeout();

Assert.AreEqual("Client did not reply", _loggerMock.RecentErrorMessage);
}
}





share|improve this answer
























  • I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

    – javirs
    Nov 23 '18 at 8:24








  • 2





    It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

    – yoger
    Nov 23 '18 at 9:18











  • but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

    – javirs
    Nov 23 '18 at 9:19






  • 2





    unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

    – Macko
    Nov 24 '18 at 20:48



















1














I think unit testing this class would be fairly simple if we just make a couple of small changes. First of all you'd surely like to get rid of the following:



Timer echoReceived = new Timer(200ms);


Waiting 200ms in a each unit test doesn't sound like a good idea. What you could do instead, is to extract this 200 ms into a class field initialized from the constructor so that you can pass it lower values, such as 1ms. But actually, you could make it even better by defining an interface like ITimer that could look something like:



interface ITimer 
{
int Interval { get; }
event EventHandler OnElapsed;
void Reset();
}


This way, in the unit test you could provide a stub e.g. implemented like this



class StubTimer 
{
[...]
void TickNow()
{
OnElapsed.Invoke( ... ) // fire the event, to avoid Thread.Sleep (waiting n miliseconds)
}
[...]
}


You probabbly should also take ShowError function as constructor parameter, assigning it to property of type like Action<ErrorArgs> .Then, you can just unit test it like so:



public void WhenClientConnected_ButThereIsNoResponse_ItShouldCallShowError() 
{
var stubHearbeatTimer = new StubTimer();
var stubTimeoutTimer = new StubTimer();

// i'm pretty sure it's possibile mock Actions with moq as well
var wasSendErrorCalled = false;
var stubErrorAction = (args) => {
wasSendErrorCalled = true;
};

var sut = new connector(stubHearbeatTimer, stubTimeoutTimer, stubErrorAction );
sut.OnClientConnected( ..dummyClient..);
stubTimeoutTimer.TickNow();

Assert.IsTrue(wasSendErrorCalled);
}


Please note it's just a pseudecode though. Hope this answers your question!






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334035%2funit-test-heartbeat-functionality%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3





    +25









    I'd go for Unit Tests, integration would require setting up some kind of connection between these two, depending on implementation it can be easier or harder. Unit Tests would simply rely on the abstraction. Just inject interfaces to the Connector and for unit testing replace them with Mocks to simulate scenarios that you designed that class for. Of course then you have to test actual implementations of Timer, Logger and ClientListener, but that's what unit tests are for.



    public class ConnectorTest
    {
    private readonly Connector _connector;
    private readonly TimerMock _receiverMock;
    private readonly TimerMock _senderMock;
    private readonly LoggerMock _loggerMock;
    private readonly ClientListenerMock _listenerMock;

    public void Setup()
    {
    _listenerMock = new ClientListenerMock();
    _receiverMock = new TimerMock();
    _senderMock = new TimerMock();
    _loggerMock = new LoggerMock();
    _connector = new Connector(_listenerMock, _receiverMock, _senderMock, _loggerMock)
    }

    public void HeartbeatSender_ShouldBeEnabled_OnceClientIsConnected()
    {
    _listenerMock.SimulateClientConnection();

    Assert.IsTrue(_senderMock.IsEnabled);
    }

    public void Error_ShouldBeLogged_WhenConnectedClientDidNotEchoed()
    {
    _listenerMock.SimulateClientConnection();

    _receiverMock.SimulateEchoTimeout();

    Assert.AreEqual("Client did not reply", _loggerMock.RecentErrorMessage);
    }
    }





    share|improve this answer
























    • I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

      – javirs
      Nov 23 '18 at 8:24








    • 2





      It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

      – yoger
      Nov 23 '18 at 9:18











    • but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

      – javirs
      Nov 23 '18 at 9:19






    • 2





      unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

      – Macko
      Nov 24 '18 at 20:48
















    3





    +25









    I'd go for Unit Tests, integration would require setting up some kind of connection between these two, depending on implementation it can be easier or harder. Unit Tests would simply rely on the abstraction. Just inject interfaces to the Connector and for unit testing replace them with Mocks to simulate scenarios that you designed that class for. Of course then you have to test actual implementations of Timer, Logger and ClientListener, but that's what unit tests are for.



    public class ConnectorTest
    {
    private readonly Connector _connector;
    private readonly TimerMock _receiverMock;
    private readonly TimerMock _senderMock;
    private readonly LoggerMock _loggerMock;
    private readonly ClientListenerMock _listenerMock;

    public void Setup()
    {
    _listenerMock = new ClientListenerMock();
    _receiverMock = new TimerMock();
    _senderMock = new TimerMock();
    _loggerMock = new LoggerMock();
    _connector = new Connector(_listenerMock, _receiverMock, _senderMock, _loggerMock)
    }

    public void HeartbeatSender_ShouldBeEnabled_OnceClientIsConnected()
    {
    _listenerMock.SimulateClientConnection();

    Assert.IsTrue(_senderMock.IsEnabled);
    }

    public void Error_ShouldBeLogged_WhenConnectedClientDidNotEchoed()
    {
    _listenerMock.SimulateClientConnection();

    _receiverMock.SimulateEchoTimeout();

    Assert.AreEqual("Client did not reply", _loggerMock.RecentErrorMessage);
    }
    }





    share|improve this answer
























    • I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

      – javirs
      Nov 23 '18 at 8:24








    • 2





      It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

      – yoger
      Nov 23 '18 at 9:18











    • but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

      – javirs
      Nov 23 '18 at 9:19






    • 2





      unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

      – Macko
      Nov 24 '18 at 20:48














    3





    +25







    3





    +25



    3




    +25





    I'd go for Unit Tests, integration would require setting up some kind of connection between these two, depending on implementation it can be easier or harder. Unit Tests would simply rely on the abstraction. Just inject interfaces to the Connector and for unit testing replace them with Mocks to simulate scenarios that you designed that class for. Of course then you have to test actual implementations of Timer, Logger and ClientListener, but that's what unit tests are for.



    public class ConnectorTest
    {
    private readonly Connector _connector;
    private readonly TimerMock _receiverMock;
    private readonly TimerMock _senderMock;
    private readonly LoggerMock _loggerMock;
    private readonly ClientListenerMock _listenerMock;

    public void Setup()
    {
    _listenerMock = new ClientListenerMock();
    _receiverMock = new TimerMock();
    _senderMock = new TimerMock();
    _loggerMock = new LoggerMock();
    _connector = new Connector(_listenerMock, _receiverMock, _senderMock, _loggerMock)
    }

    public void HeartbeatSender_ShouldBeEnabled_OnceClientIsConnected()
    {
    _listenerMock.SimulateClientConnection();

    Assert.IsTrue(_senderMock.IsEnabled);
    }

    public void Error_ShouldBeLogged_WhenConnectedClientDidNotEchoed()
    {
    _listenerMock.SimulateClientConnection();

    _receiverMock.SimulateEchoTimeout();

    Assert.AreEqual("Client did not reply", _loggerMock.RecentErrorMessage);
    }
    }





    share|improve this answer













    I'd go for Unit Tests, integration would require setting up some kind of connection between these two, depending on implementation it can be easier or harder. Unit Tests would simply rely on the abstraction. Just inject interfaces to the Connector and for unit testing replace them with Mocks to simulate scenarios that you designed that class for. Of course then you have to test actual implementations of Timer, Logger and ClientListener, but that's what unit tests are for.



    public class ConnectorTest
    {
    private readonly Connector _connector;
    private readonly TimerMock _receiverMock;
    private readonly TimerMock _senderMock;
    private readonly LoggerMock _loggerMock;
    private readonly ClientListenerMock _listenerMock;

    public void Setup()
    {
    _listenerMock = new ClientListenerMock();
    _receiverMock = new TimerMock();
    _senderMock = new TimerMock();
    _loggerMock = new LoggerMock();
    _connector = new Connector(_listenerMock, _receiverMock, _senderMock, _loggerMock)
    }

    public void HeartbeatSender_ShouldBeEnabled_OnceClientIsConnected()
    {
    _listenerMock.SimulateClientConnection();

    Assert.IsTrue(_senderMock.IsEnabled);
    }

    public void Error_ShouldBeLogged_WhenConnectedClientDidNotEchoed()
    {
    _listenerMock.SimulateClientConnection();

    _receiverMock.SimulateEchoTimeout();

    Assert.AreEqual("Client did not reply", _loggerMock.RecentErrorMessage);
    }
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 22 '18 at 21:45









    yogeryoger

    312210




    312210













    • I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

      – javirs
      Nov 23 '18 at 8:24








    • 2





      It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

      – yoger
      Nov 23 '18 at 9:18











    • but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

      – javirs
      Nov 23 '18 at 9:19






    • 2





      unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

      – Macko
      Nov 24 '18 at 20:48



















    • I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

      – javirs
      Nov 23 '18 at 8:24








    • 2





      It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

      – yoger
      Nov 23 '18 at 9:18











    • but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

      – javirs
      Nov 23 '18 at 9:19






    • 2





      unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

      – Macko
      Nov 24 '18 at 20:48

















    I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

    – javirs
    Nov 23 '18 at 8:24







    I think I dont get your solution. You wrote like 50 lines of code (with potential bug's) to test that heartbeatSemder.isEnabled = true; happened. But you don't care about heartbeat pulses actually being sent or not. Just that this line was called. As for the second one.. I don't know how you simulate a timeout but I fear you just call an event so .. .the heartbeat system is not tested at all.

    – javirs
    Nov 23 '18 at 8:24






    2




    2





    It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

    – yoger
    Nov 23 '18 at 9:18





    It's more or less just to supplement the description I made. I didn't create full test solution for your pseudocode. Just provided an idea of how to unit test it.

    – yoger
    Nov 23 '18 at 9:18













    but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

    – javirs
    Nov 23 '18 at 9:19





    but the question is how to unit test that the timers ar correct, that the autoresets are ok, and that the whole heartbeat solution works

    – javirs
    Nov 23 '18 at 9:19




    2




    2





    unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

    – Macko
    Nov 24 '18 at 20:48





    unit testing timers are not easy because you they are asynchronous by design, so approch with unit testing is very good idea (abstracting real network connection and everything which could change the result of a test breaking repeatable unit test rule). use some mocking library like moq, refactor classes to relay on abstractions (interfaces), then mock timers or other components not related to logic u want to test.

    – Macko
    Nov 24 '18 at 20:48













    1














    I think unit testing this class would be fairly simple if we just make a couple of small changes. First of all you'd surely like to get rid of the following:



    Timer echoReceived = new Timer(200ms);


    Waiting 200ms in a each unit test doesn't sound like a good idea. What you could do instead, is to extract this 200 ms into a class field initialized from the constructor so that you can pass it lower values, such as 1ms. But actually, you could make it even better by defining an interface like ITimer that could look something like:



    interface ITimer 
    {
    int Interval { get; }
    event EventHandler OnElapsed;
    void Reset();
    }


    This way, in the unit test you could provide a stub e.g. implemented like this



    class StubTimer 
    {
    [...]
    void TickNow()
    {
    OnElapsed.Invoke( ... ) // fire the event, to avoid Thread.Sleep (waiting n miliseconds)
    }
    [...]
    }


    You probabbly should also take ShowError function as constructor parameter, assigning it to property of type like Action<ErrorArgs> .Then, you can just unit test it like so:



    public void WhenClientConnected_ButThereIsNoResponse_ItShouldCallShowError() 
    {
    var stubHearbeatTimer = new StubTimer();
    var stubTimeoutTimer = new StubTimer();

    // i'm pretty sure it's possibile mock Actions with moq as well
    var wasSendErrorCalled = false;
    var stubErrorAction = (args) => {
    wasSendErrorCalled = true;
    };

    var sut = new connector(stubHearbeatTimer, stubTimeoutTimer, stubErrorAction );
    sut.OnClientConnected( ..dummyClient..);
    stubTimeoutTimer.TickNow();

    Assert.IsTrue(wasSendErrorCalled);
    }


    Please note it's just a pseudecode though. Hope this answers your question!






    share|improve this answer




























      1














      I think unit testing this class would be fairly simple if we just make a couple of small changes. First of all you'd surely like to get rid of the following:



      Timer echoReceived = new Timer(200ms);


      Waiting 200ms in a each unit test doesn't sound like a good idea. What you could do instead, is to extract this 200 ms into a class field initialized from the constructor so that you can pass it lower values, such as 1ms. But actually, you could make it even better by defining an interface like ITimer that could look something like:



      interface ITimer 
      {
      int Interval { get; }
      event EventHandler OnElapsed;
      void Reset();
      }


      This way, in the unit test you could provide a stub e.g. implemented like this



      class StubTimer 
      {
      [...]
      void TickNow()
      {
      OnElapsed.Invoke( ... ) // fire the event, to avoid Thread.Sleep (waiting n miliseconds)
      }
      [...]
      }


      You probabbly should also take ShowError function as constructor parameter, assigning it to property of type like Action<ErrorArgs> .Then, you can just unit test it like so:



      public void WhenClientConnected_ButThereIsNoResponse_ItShouldCallShowError() 
      {
      var stubHearbeatTimer = new StubTimer();
      var stubTimeoutTimer = new StubTimer();

      // i'm pretty sure it's possibile mock Actions with moq as well
      var wasSendErrorCalled = false;
      var stubErrorAction = (args) => {
      wasSendErrorCalled = true;
      };

      var sut = new connector(stubHearbeatTimer, stubTimeoutTimer, stubErrorAction );
      sut.OnClientConnected( ..dummyClient..);
      stubTimeoutTimer.TickNow();

      Assert.IsTrue(wasSendErrorCalled);
      }


      Please note it's just a pseudecode though. Hope this answers your question!






      share|improve this answer


























        1












        1








        1







        I think unit testing this class would be fairly simple if we just make a couple of small changes. First of all you'd surely like to get rid of the following:



        Timer echoReceived = new Timer(200ms);


        Waiting 200ms in a each unit test doesn't sound like a good idea. What you could do instead, is to extract this 200 ms into a class field initialized from the constructor so that you can pass it lower values, such as 1ms. But actually, you could make it even better by defining an interface like ITimer that could look something like:



        interface ITimer 
        {
        int Interval { get; }
        event EventHandler OnElapsed;
        void Reset();
        }


        This way, in the unit test you could provide a stub e.g. implemented like this



        class StubTimer 
        {
        [...]
        void TickNow()
        {
        OnElapsed.Invoke( ... ) // fire the event, to avoid Thread.Sleep (waiting n miliseconds)
        }
        [...]
        }


        You probabbly should also take ShowError function as constructor parameter, assigning it to property of type like Action<ErrorArgs> .Then, you can just unit test it like so:



        public void WhenClientConnected_ButThereIsNoResponse_ItShouldCallShowError() 
        {
        var stubHearbeatTimer = new StubTimer();
        var stubTimeoutTimer = new StubTimer();

        // i'm pretty sure it's possibile mock Actions with moq as well
        var wasSendErrorCalled = false;
        var stubErrorAction = (args) => {
        wasSendErrorCalled = true;
        };

        var sut = new connector(stubHearbeatTimer, stubTimeoutTimer, stubErrorAction );
        sut.OnClientConnected( ..dummyClient..);
        stubTimeoutTimer.TickNow();

        Assert.IsTrue(wasSendErrorCalled);
        }


        Please note it's just a pseudecode though. Hope this answers your question!






        share|improve this answer













        I think unit testing this class would be fairly simple if we just make a couple of small changes. First of all you'd surely like to get rid of the following:



        Timer echoReceived = new Timer(200ms);


        Waiting 200ms in a each unit test doesn't sound like a good idea. What you could do instead, is to extract this 200 ms into a class field initialized from the constructor so that you can pass it lower values, such as 1ms. But actually, you could make it even better by defining an interface like ITimer that could look something like:



        interface ITimer 
        {
        int Interval { get; }
        event EventHandler OnElapsed;
        void Reset();
        }


        This way, in the unit test you could provide a stub e.g. implemented like this



        class StubTimer 
        {
        [...]
        void TickNow()
        {
        OnElapsed.Invoke( ... ) // fire the event, to avoid Thread.Sleep (waiting n miliseconds)
        }
        [...]
        }


        You probabbly should also take ShowError function as constructor parameter, assigning it to property of type like Action<ErrorArgs> .Then, you can just unit test it like so:



        public void WhenClientConnected_ButThereIsNoResponse_ItShouldCallShowError() 
        {
        var stubHearbeatTimer = new StubTimer();
        var stubTimeoutTimer = new StubTimer();

        // i'm pretty sure it's possibile mock Actions with moq as well
        var wasSendErrorCalled = false;
        var stubErrorAction = (args) => {
        wasSendErrorCalled = true;
        };

        var sut = new connector(stubHearbeatTimer, stubTimeoutTimer, stubErrorAction );
        sut.OnClientConnected( ..dummyClient..);
        stubTimeoutTimer.TickNow();

        Assert.IsTrue(wasSendErrorCalled);
        }


        Please note it's just a pseudecode though. Hope this answers your question!







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 22:20









        Mateusz UrbanMateusz Urban

        16816




        16816






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334035%2funit-test-heartbeat-functionality%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()