← Back to team overview

nunit-core team mailing list archive

[Bug 893919] Re: DelayedConstraint fails polling properties on references which are initially null

 

** Changed in: nunit-3.0
       Status: Triaged => In Progress

** Changed in: nunit-3.0
       Status: In Progress => Fix Committed

-- 
You received this bug notification because you are a member of NUnit
Core Developers, which is the registrant for NUnit Framework.
https://bugs.launchpad.net/bugs/893919

Title:
  DelayedConstraint fails polling properties on references which are
  initially null

Status in NUnit Test Framework:
  Fix Committed
Status in NUnit V2 Test Framework:
  Triaged

Bug description:
  Having seen the great progress made on bug #890129, I've been using the After() constraint even more!
  (Still using v2.5.10.11092)

  I noticed a quirk with how (properties of) objects which are initially
  null are polled.

  An example:
      string statusString = null; // object starts off as null

      var worker = new BackgroundWorker();
      worker.RunWorkerCompleted += delegate { statusString = "finished"; /* object non-null after work */ };
      worker.DoWork += delegate { Thread.Sleep(TimeSpan.FromSeconds(1)); /* simulate work */ };
      worker.RunWorkerAsync();
           
      Assert.That(() => statusString, Has.Length.GreaterThan(0).After(3000, 100));

  The assert will fail after its first poll, reporting:
           System.ArgumentNullException : Value cannot be null.
           Parameter name: actual

  I assume this is because the 'statusString' object is null, so fetching the 'Length' property causes a ArgumentNullException.
  However, I'd expect that the test would at least continue to try to poll even if the value is initially null, in case it gets initialised before the timeout.

  A few simple workarounds exist:

  Adding a prior null check to the constraint:
      Assert.That(() => statusString, Is.Not.Null.With.Length.GreaterThan(0).After(3000, 100));

  Or adding another separate DelayedConstraint before the Assert which checks for non-null, like this:
      Assert.That(() => statusString, Is.Not.Null.After(3000, 100));
      Assert.That(() => statusString, Has.Length.GreaterThan(0).After(3000, 100));

  Perhaps that is because each constraint must pass or timeout before
  the next is run. The documentation doesn't specify whether each
  'After' assert is run on a separate thread or whether earlier ones
  block.

To manage notifications about this bug go to:
https://bugs.launchpad.net/nunit-3.0/+bug/893919/+subscriptions


References