Search code examples
.netvb.netunit-testingmockingnsubstitute

How can I mock a property setter in NSubstitute


Here is what I tried doing:

    Public Interface IDAO(Of T) : Inherits IDAO
        Default Property Value(i As ULong) As T
        Function Append(ts As ICollection(Of T)) As ULong
        Function Remove(f As Predicate(Of T)) As ICollection(Of T)
        Function GetRestricted(f As Predicate(Of T)) As ICollection(Of T)
        Function RemoveFirst(f As Predicate(Of T)) As T
        Function GetFirst(f As Predicate(Of T)) As T
    End Interface
'...
_mock.WhenForAnyArgs(
    Function(mock As IDAO(Of T)) mock.Value(Arg.Any(Of ULong)) = Arg.Any(Of T)()
).Do(
    Sub(c As Core.CallInfo) Exit Sub 'Value(i) ... Set(v) ... _inner.data(i) = v                                                                                                 
)

The pattern selector Function(mock As IDAO(Of T)) mock.Value(Arg.Any(Of ULong)) = Arg.Any(Of T)() does not work; and even if it did I have no clue how I would utilise the CallInfo object in the Do statement.


Solution

  • I'm not sure on how to do this in VB, but here is how to do it in C# and hopefully you or another person can translate.

        public interface IDao
        {
            ulong Value { get; set; }
        }
    
        [SuppressMessage("Argument specification", "NS3002:Can not find an argument to this call.", Justification = "Used in property set")]
        [Fact]
        public void PropertySetExample() {
            var sub = Substitute.For<IDao>();
            var value = 0ul;
            sub.WhenForAnyArgs(x => x.Value = 0ul).Do(callInfo =>
              // This will be called when sub.Value is set. 
              // For this example we just assign to a local variable.
              value = callInfo.Arg<ulong>()
            );
    
            sub.Value = 42;
    
            Assert.Equal(42ul, value);
        }
    

    (The SuppressMessage is only required for NSubstitute.Analyzers as it is not sure about the arguments to the property set.)