AutoFixture icon indicating copy to clipboard operation
AutoFixture copied to clipboard

AutoNSubstitute: Problem overriding Returns value

Open Ergamon opened this issue 5 years ago • 0 comments

Today I stumbled about a bug and I am a little confused why it is happening.

The test code is around some bad legacy code which sadly cannot be changed:

 public interface IValue
  {
  }

  public interface IItem
  {
    IValue Value { get; }
  }

  public interface ISpecialItem : IItem
  {
    new IValue Value { get; set; }
  }

  public interface IFoo
  {
    IList<ISpecialItem> Items { get; }
  }

So basically there is an interface IItem having a readonly property and for some reason the writer of this legacy code wanted to have a setter for an inherited interface ISpecialItem. Therefore the new keyword. In another interface IFoo is a property with a list of these special items as data type.

    [Fact]
    private void Test()
    {
      var customization = new AutoNSubstituteCustomization()
      {
        ConfigureMembers = true,
      };

      var fixture = new Fixture();
      fixture.Customize(customization);

      var foo = fixture.Create<IFoo>();

      // Reading the property once fixes it
      // var items = foo.Items; 

      foo.Items.ReturnsNull();
    }

In a test the interface IFoo is created with AutoFixture but someone wanted to test a special case where the property returns null. For some strange reason an exception is thrown.

Can not return value of type IList`1 for ISpecialItem.set_Value (expected type Void).

Investigating the exception further I found that AutoFixture is trying to set the Value property of the special items to return null by calling NSubstitute. And NSubstitute throws an exception not allowing Returns statements on properties having a setter.

The fixture creates the IFoo proxy with an Items property returning 3 ISpecialItem proxies due to the ConfigureMembers being true in the customization.

By calling the ReturnsNull extension method I override the proxies return value of the Items property, but I dont understand why this results in a call to ISpecialItem.Value.ReturnsNull() ?

With my limited understanding of AutoNSubstitute it gets even stranger for me. If I read the property at some point before calling the Returns statement everything works fine.

If needed I can attach a sample solution.

Thx for any help Gerald

Ergamon avatar Jan 08 '20 19:01 Ergamon