Moq how to correctly mock set only properties

匿名 (未验证) 提交于 2019-12-03 01:19:01

问题:

What is the correct way for dealing with interfaces the expose set-only properties with Moq? Previously I've added the other accessor but this has bled into my domain too far with random throw new NotImplementedException() statements throughout.

I just want to do something simple like:

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

But this yields a compile error of The property 'SetOnlyValue' has no getter

回答1:

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" );     } }


回答2:

Thanks Ruben!

And to help someone with a VB.Net gotcha this is the same code in 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()>()>

Important here is that you can't use a single-line Function lambda since this will be interpreted as an expression that returns a value, rather than the assignment statement that you are after. This is since VB.Net uses the single equal sign not only for assignment but also for equality comparison, and so trying to do

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

will be interpreted as a boolean comparison of the s.AA-value and the It.IsAny(Of String)(), thus invoking the getter, which will again result in a compile error. Instead you want to use a Sub lambda (or possibly a multi-line Function lambda).

If you have a getter on the property, however, a Function lambda will still work.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!