DelayedConstraint doesn't appear to poll properties of objects
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
NUnit Framework |
Fix Released
|
High
|
Charlie Poole | ||
NUnit V2 |
Fix Released
|
Medium
|
Charlie Poole |
Bug Description
Using 2.5.10.11092.
I've just been exploring the new (to me) fluent/constraints syntax, specifically the After() constraint and am very impressed.
I've already learnt not to pass by value (!), however, I thought that a pass-by-reference should be ok.
For example:
var worker = new BackgroundWorker();
var list = new List<int>();
The documentation states that its "intended use is with delegates and references", so I'd expect the 'list' object reference to be polled, and after about 1 second, for the constraint to pass.
However, I have to wait for the full 5 seconds before the test succeeds.
The obvious work around is to convert the 'list' object to a delegate:
This works fine, and still look ok (to me).
However, I wondered if this is deliberate or unavoidable behaviour or just a bug...
Changed in nunitv2: | |
status: | In Progress → Fix Committed |
Changed in nunit-3.0: | |
status: | New → Triaged |
importance: | Undecided → High |
assignee: | nobody → Charlie Poole (charlie.poole) |
Changed in nunit-3.0: | |
milestone: | none → 2.9.6 |
Changed in nunitv2: | |
status: | Fix Committed → Fix Released |
Changed in nunit-3.0: | |
status: | Triaged → In Progress |
Changed in nunit-3.0: | |
status: | In Progress → Fix Committed |
Changed in nunit-3.0: | |
status: | Fix Committed → Fix Released |
When the DelayedConstraint is used with an object (value or reference) it simply waits the specified amount of time before evaluating the base constraint and no polling takes place. When it is used with a reference to an object or with a delegate, polling is used.
So, the following should work as expected: EqualTo( 1).After( 5000, 100));
Assert.That(ref list, Has.Count.
In the example you give, polling could effectively have been used, since the actual value tested is a property of the object and not the object itself. In other cases, this would not work, since the actual value argument is evaluated only once, before calling Assert.That(). A simple example...
var worker = new BackgroundWorker(); RunWorkerComple ted += delegate { x = 1; } RunWorkerAsync( ); 1).After( 5000);
int x = 0;
worker.
worker.DoWork += delegate { Thread.Sleep(1); }
worker.
Assert.That(x, Is.EqualTo(
The value of x used in the test is zero because x was evaluated before calling Assert.That().
I'll give this a little more thought to determine whether NUnit can make a runtime distinction between those arguments where polling might make sense and those where it would not. Clearly, we can't make the distinction syntactically.
Charlie