0
votes

I'm trying to write a custom contrain for nunit (3) in vb.net Simplest example (following the docs) would be:

Namespace MYConstraints
    Public Class MyConstraint
        Inherits NUnit.Framework.Constraints.Constraint

        Public Overrides Function ApplyTo(Of TActual)(actual As TActual) As NUnit.Framework.Constraints.ConstraintResult
            Throw New NotImplementedException()
        End Function
    End Class

End Namespace

(The ApplyTo definition was added by Visual Studio automatically even, when I inherited the nunit Constraint class)

Problem is, it won't compile!

I get two errors:

BC30518 Overload resolution failed because no accessible 'That' can be called with these arguments:

'Public Shared Overloads Sub That(Of TActual)(del As ActualValueDelegate(Of TActual), expr As IResolveConstraint)': Type parameter 'TActual' cannot be inferred.

'Public Shared Overloads Sub That(Of TActual)(actual As TActual, expression As IResolveConstraint)': Type parameter 'TActual' cannot be inferred.

And

BC30935 Member 'Public MustOverride Overloads Function ApplyTo(Of TActual)(actual As TActual) As ConstraintResult' that matches this signature cannot be overridden because the class 'Constraint' contains multiple members with this same name and signature:

'Public MustOverride Overloads Function ApplyTo(Of TActual)(actual As TActual) As ConstraintResult' 'Public Overridable Overloads Function ApplyTo(Of TActual)(ByRef actual As TActual) As ConstraintResult'

Looking at the nunit source for the Constain class I see that they have defined two variants with the same signature:

/// <summary>
/// Applies the constraint to an actual value, returning a ConstraintResult.
/// </summary>
/// <param name="actual">The value to be tested</param>
/// <returns>A ConstraintResult</returns>
public abstract ConstraintResult ApplyTo<TActual>(TActual actual);

/// <summary>
/// Applies the constraint to an ActualValueDelegate that returns
/// the value to be tested. The default implementation simply evaluates
/// the delegate but derived classes may override it to provide for
/// delayed processing.
/// </summary>
/// <param name="del">An ActualValueDelegate</param>
/// <returns>A ConstraintResult</returns>
public virtual ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> del)
{
#if ASYNC
    if (AsyncInvocationRegion.IsAsyncOperation(del))
        using (var region = AsyncInvocationRegion.Create(del))
            return ApplyTo(region.WaitForPendingOperationsToComplete(del()));
#endif
    return ApplyTo(GetTestObject(del));
}

One is abstract with a pass-by-value parameter and the other is virtual with a reference param, but that's surely not enough to distinguish them when calling?

The tooltip error in Visual Studio (VS 2015 Professional if it makes a difference) is: enter image description here So it looks like it's interpreting the ActualValueDelegate<TActual> as a ByRef TActual in vb.net

So, two questions:

  1. How is this possible? (Is this allowed in C# but not vb.net? or have I misunderstood something?) - this is just that I am curious :)

  2. How should I write a custom constrain in vb.net? (Does anyone have an example?) This is my main question :)

I'm increasingly convinced this is a bug - something valid in C# that doesn't translate to vb.net maybe. Have created a bug at https://github.com/nunit/nunit/issues/2263

1
You haven't given the code that is failing to compile - that is the code that uses Assert.That with this constraint. Please add that to get more help.Charlie
Hi Charlie, I'm running into the same VB compile errors. re: The two overloads you list do not have the same signature. VB compiler is displaying that error message indicating it thinks the two overloads are the same. re: There is no TActual ByRef.: The VB compiler is displaying that the ApplyTo signature takes "By Ref Actual As TActual". I've tried every combination of overrides, shadows, overloads, etc. that I can think of. I can't get this to complete.CoolBreeze
Hi Charlie, Also, as the OP mentioned I let VB compiler generate the method snippets. The VB doesn't like the generated snippets. I was able to create a function: Public Overrides Function ApplyTo(Of TActual)(Actual As ActualValueDelegate(Of TActual)) As Constraints.ConstraintResult. I'm guessing the problem is that the NUnit C# code is not translating to VB method signatures as one would expect. To solve this problem I've had to downgrade to an earlier version of Nunit.CoolBreeze
Did some investigation. 1) I downgraded NUnit to each version from 3.7 to 2.6.3. I got the same errors. 2) I have two projects subclassing Nunit Constraint class. Project 1 custom constraint compiles successfully, but can't see Constraint metadata when I click on Go to Definfition; project 2 I get errors as listed by OP, I can see Constraint Meta Data. I compared syntax between both custom constraints and made sure they are the same. Both projects are: VS 2017 Community Edition, .Net 4, VB.CoolBreeze
@Charlie, Yesterday, I played around with trying to get a VB version to work for some time. The only solution I could get to work was to create a C# project in my VB solution and convert my VB custom constraint to C#.CoolBreeze

1 Answers

0
votes

It seems to be confirmed as a bug in nunit. See https://github.com/nunit/nunit/issues/2263