Подтвердить что ты не робот

Moq, как правильно имитировать только свойства

Каков правильный способ работы с интерфейсами, чтобы показать свойства set-only с помощью Moq? Раньше я добавил другой аксессуар, но это слишком сильно ударило в мой домен со случайными инструкциями throw new NotImplementedException().

Я просто хочу сделать что-то простое:

mock.VerifySet(view => view.SetOnlyValue, Times.Never());

Но это дает ошибку компиляции The property 'SetOnlyValue' has no getter

4b9b3361

Ответ 1

public class Xyz
{
    public virtual string AA { set{} }
}
public class VerifySyntax
{
    [Fact]
    public void ThisIsHow()
    {
        var xyz = new Mock<Xyz>();
        xyz.Object.AA = "bb";
        // Throws:
        xyz.VerifySet( s => s.AA = It.IsAny<string>(), Times.Never() );
    }
}
public class SetupSyntax
{
    [Fact]
    public void ThisIsHow()
    {
        var xyz = new Mock<Xyz>();
        xyz.SetupSet( s => s.AA = It.IsAny<string>() ).Throws( new InvalidOperationException(  ) );
        Assert.Throws<InvalidOperationException>( () => xyz.Object.AA = "bb" );
    }
}

Ответ 2

Спасибо Рубен!

И чтобы помочь кому-то с VB.Net получить этот код в VB.Net:

Public Interface Xyz
    WriteOnly Property AA As String
End Interface
Public Class VerifySyntax
    <Fact()>
    Public Sub ThisIsHow()
        Dim xyz = New Mock(Of Xyz)
        xyz.Object.AA = "bb"
        ' Throws:
        xyz.VerifySet(Sub(s) s.AA = It.IsAny(Of String)(), Times.Never())
    End Sub
End Class
Public Class SetupSyntax
    <Fact()>
    Public Sub ThisIsHow()
        Dim xyz = New Mock(Of Xyz)
        xyz.SetupSet(Sub(s) s.AA = It.IsAny(Of String)()).Throws(New InvalidOperationException())
        Assert.Throws(Of InvalidOperationException)(Sub() xyz.Object.AA = "bb")
    End Sub
End Class

Важно отметить, что нельзя использовать однострочную функцию lambda, поскольку это будет интерпретироваться как выражение, возвращающее значение, а не оператор присваивания, который вы используете. Это происходит потому, что VB.Net использует один знак равенства не только для присваивания, но и для сравнения равенства, и поэтому пытается сделать

        xyz.VerifySet(Function(s) s.AA = It.IsAny(Of String)(), Times.Never())

будет интерпретироваться как логическое сравнение значения s.AA и It.IsAny(Of String)(), вызывая, таким образом, getter, что также приведет к ошибке компиляции. Вместо этого вы хотите использовать Sub лямбда (или, возможно, многострочную функцию лямбда).

Если у вас есть свойство getter, функция lambda все равно будет работать.