Note that there are some explanatory texts on larger screens.

plurals
  1. POUnitTesting a threaded class, avoiding Thread.Sleep() in test?
    primarykey
    data
    text
    <p>I'm trying to figure out the best way to unit test this class:</p> <pre><code>public class FileGroupGarbageCollector { private Task _task; private readonly AutoResetEvent _event = new AutoResetEvent(false); public void Start() { _task = Task.Factory.StartNew(StartCollecting); } public void Stop() { _event.Set(); } private void StartCollecting() { do { Process(); } while (!_event.WaitOne(60000, false)); } private void Process() { /* do some work to the database and file system */ } } </code></pre> <p>It's not supposed to be the most well formed class, just trying to figure out something!</p> <p>I then have a unit test where I want to start and then stop the service, asserting the the private 'Processs' method did something to the database or filesystem.</p> <p>My unit test is as follows (nunit):</p> <pre><code> [Test] public void TestStart() { var fg = new FileGroupGarbageCollector(30000); fg.Start(); Thread.Sleep(5000); // i hate this! fg.Stop(); // assert it did what i wanted it to do! } </code></pre> <p>Is there any way or any nice pattern that can be used here so I can avoid Thread.Sleep()? I hate the idea of sleeping in a unit test (let alone in production code), but I refuse to just test private functionality! I want to test the public interface of this class.</p> <p>Any answers are greatly appreciated :)</p> <p><strong>UPDATE AFTER ANSWER</strong></p> <p>I went with the IoC way of things and it works really nicely :)</p> <blockquote> <p>public interface IEventFactory { IEvent Create(); }</p> </blockquote> <pre><code>public interface IEvent { bool WaitOne(int timeout); void Set(); } </code></pre> <p>Then my mock objects (using Moq):</p> <pre><code> var mockEvent = new Mock&lt;IEvent&gt;(); var mockEventFactory = new Mock&lt;IEventFactory&gt;(); mockEvent.Setup(x =&gt; x.WaitOne(It.IsAny&lt;int&gt;())).Returns(true); mockEvent.Setup(x =&gt; x.Set()); mockEventFactory.Setup(x =&gt; x.Create()).Returns(mockEvent.Object); </code></pre> <p>So instantly a call to IEvent.WaitOne() returns true and exits, so no need for the Thread.Sleep()!</p> <p>:)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload