Moq property with protected setter
I want to Moq next object:
abstract class Foo
{
public string Bar { get; protected set; }
}
so that new Mock<Foo>().Bar
return "Blah"
.
How can I do that?
fooMock.SetupGet<开发者_如何学C;string>(s => s.Bar).Returns("Blah");
throws
Failure: System.NotSupportedException : Invalid setup on a non-virtual member: s => s.Date
and
fooMock.Protected().SetupGet<string>("Bar").Returns("Blah");
throws
To specify a setup for public property StatementSection.Date, use the typed overloads
Like Felice (+1) said mocking creates a proxy which means you need to either make things virtual (so Moq can work its proxying magic and override the property).
As an alternative if you just want to squirt in a value you can manually stub the class you want to test and expose a means to get at the setter:-
public class FooStub : Foo {
public SetBar(string newValue) {
Bar = newValue;
}
}
Since mocking is done by creating a proxy of your class,only virtual function/property can be "moqued"
Here's an example of providing a proxy class that can modify the protected property via it's constructor (MyClass
is proxied by MyClassProxy
). Tests are XUnit.
public class MyClassEqualityComparerTests
{
/// <summary>
/// Normal class
/// </summary>
public class MyClass
{
public Guid Id { get; protected set; }
}
/// <summary>
/// Proxy class facilitates setting of protected Id
/// </summary>
public class MyClassProxy : MyClass
{
public MyClassProxy(Guid id)
{
this.Id = id;
}
}
public class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
public bool Equals(MyClass x, MyClass y)
{
return x.Id.Equals(y.Id);
}
public int GetHashCode(MyClass obj)
{
return obj.Id.GetHashCode();
}
}
[Fact]
public void CompareSameMyClasss_ShouldBeEqual()
{
var sharedGuid = Guid.NewGuid();
var myClass1 = new MyClassProxy(sharedGuid);
var myClass2 = new MyClassProxy(sharedGuid);
//arrange
var myClassEqualityComparer = new MyClassEqualityComparer();
//act
bool equals = myClassEqualityComparer.Equals(myClass1, myClass2);
//assert
equals.Should().BeTrue();
}
[Fact]
public void CompareDifferentMyClasss_ShouldNotBeEqual()
{
var myClass1 = new MyClassProxy(Guid.NewGuid());
var myClass2 = new MyClassProxy(Guid.NewGuid());
//arrange
var myClassEqualityComparer = new MyClassEqualityComparer();
//act
bool equals = myClassEqualityComparer.Equals(myClass1, myClass2);
//assert
equals.Should().BeFalse();
}
}
精彩评论