Reputation: 33098
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
Upvotes: 14
Views: 10167
Reputation: 3236
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
<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
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.
Upvotes: 3
Reputation: 61795
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" );
}
}
Upvotes: 18