如何使用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>();
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" );
}
}
view => view.SetOnlyValue
调用getter,而像view => view.SetOnlyValue = 0
这样的东西将调用setter。为了避免使用It
之类的东西,在Setup/VerifySet
的上下文中,第一种风格(getter)被解释为引用setter,即使底层代码是getter调用。没有我感觉你正在解释我之前的答案所暗示的那种魔法。 - Ruben Bartelink感谢Ruben!
为了帮助有关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
xyz.VerifySet(Function(s) s.AA = It.IsAny(Of String)(), Times.Never())
这段代码将被解释为 s.AA-value 和 It.IsAny(Of String)() 的布尔比较,从而调用 getter,这将导致编译错误。相反,你应该使用一个 Sub lambda(或可能是多行 Function lambda)。
但如果在属性上有一个getter,Function lambda仍然有效。
view => view.SetOnlyValue'生成了
The property 'SetOnlyValue' has no getter'。这是因为这段代码被解释为对getter的调用。在读写情况下,VerifySet
遍历表达式并确定所需的是属性setter上的期望。在只写情况下,这会遇到编译器错误。我们需要假设OP在这里不是愚蠢的,并且不是想给自己增加工作量,而是在问“如何避免做额外的无用功”。 - Ruben BartelinkVerifySet(v => v.SetOnlyProp)
。相反,我必须使用VerifySet(v => v.SetOnlyProp = It.IsAny<X>())
。是这样吗? - superjos