0

I am trying to use TDD in my latest project, however I've got stucked trying to implement this.

I need to send a ping message to a TcpListener at an interval. I have implemented a TCP Service with reference to this question. The TDD process up to this stage is all well. The TcpService is used by an engine that control the whole flow of the program.

Now comes in the part where I need to send some message every few seconds. My idea is to create another service that uses timer internally, and inject TcpService to it in order to for it to be able to send message via TCP.

Is this a viable solution? If so, how do I test it? If not, can anyone point me to the right direction?

Thanks.

Community
  • 1
  • 1
Yaobin Then
  • 2,662
  • 1
  • 34
  • 54

2 Answers2

2

In general, good unit tests are short, fast, contain no logic, involve no IO, test a single thing, assert on a single object, independent, and reliable.

The single thing being tested is known as the System Under Test (SUT). All dependencies of the SUT should be able to be configured during the test.

Try to avoid logic, IO, and asynchronous calls in unit tests. These tend to make for brittle, unreliable, and slow tests. I find Roy Osherove's videos to be a good starting point for TDD and Unit Testing. Here's Roy Osherove's definition of a Unit Test.

Writing testable code takes some getting used to. A good place to start is Uncle Bob's SOLID principles. I find that the Single Responsibility Principle (SRP), Dependency Inversion Principle (DIP), along with the Don't Repeat Yourself (DRY) Principle give the best mileage.

Focus on writing unit tests that execute the core logic of you system, one small bit of logic at a time. You don't actually want to test that the network is working in a unit test, but you do want to test the logic at either end of the connection.

Using timers in automated tests should be avoided. You want to get at the logic inside of the timer. Timers lead to slow, unreliable tests.

If you really want to test the network connection, you are really writing an integration test. There's nothing saying you shouldn't do this, but when you're writing unit tests, your focus is on core logic.

You might want to consider using a mocking framework such as Moq. Here's an article on Writing Unit Tests with NUnit and Moq. You don't need to use a mocking framework, since you can just create concrete instances inside the unit tests, but it's good to know you have options.

Community
  • 1
  • 1
Jerome
  • 101
  • 7
  • Thanks for the input! FYI i'm not trying to test the network connection, but rather the behaviour of a system that will send a message every few seconds. I realized I can make use of System.Timers.Timer to achieve that without testing it (because it's BCL?) I have the test for the send method. Should I really test that the send method will be called every few seconds? If not, will it break TDD rules for writing code for the timed event without test? Sorry for the bad description, hope you understand. Thanks. – Yaobin Then Apr 17 '14 at 03:27
  • 1
    I don't see much value in testing that the System.Timers.Timer actually ticks. What I would test is any code that starts / stops the timer, the logic on the receiving end of the connection, and the logic that processes responses. There are no hard and fast rules on what you should test, but you should focus on things that are likely to fail. The timer itself isn't likely to fail. – Jerome Apr 17 '14 at 17:34
1

Create an interface ScheduledTask that TcpService implements. Create a Scheduler class that takes two constructor parameters: interval in milliseconds and a ScheduledTask. Now you can write unit tests for Scheduler using an interval of 1 millisecond and a mock ScheduledTask.

Mike Stockdale
  • 5,256
  • 3
  • 29
  • 33