Moq如何正确模拟仅设置属性

使用Moq处理暴露的仅设置属性的接口的正确方法是什么? 以前我已经添加了另一个访问者,但是这已经过了很多随机throw new NotImplementedException()语句已经流入我的域名。

我只想做一些简单的事情:

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

但这会产生编译错误。 The property 'SetOnlyValue' has no getter

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

谢谢鲁本!

并帮助有VB.Net陷阱的人这是VB.Net中的相同代码:

 Public Interface Xyz WriteOnly Property AA As String End Interface Public Class VerifySyntax  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  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 lambda(或者可能是多行函数lambda)。

但是,如果你在属性上有一个getter,那么一个Function lambda仍然可以工作。