Reputation:
I'm trying to get FakeItEasy 1.25.3 to throw an exception on a property; the setter test works fine but the getter does not throw an exception as expected. What am I doing wrong?
public interface IMisc
{
int IntProperty { get; set; }
}
// Setter throws exception as expected.
[Test]
public void Property_Setter_Throws()
{
var driver = A.Fake<IMisc>();
A.CallTo(driver).Where(call => call.Method.Name == "set_IntProperty")
.Throws(new Exception());
var i = driver.IntProperty;
Assert.That( delegate { driver.IntProperty = 3; }, Throws.Exception);
}
// Getter does not throw exception as expected.
[Test]
public void Property_Getter_Throws()
{
var driver = A.Fake<IMisc>();
A.CallTo(driver).Where(call => call.Method.Name == "get_IntProperty")
.Throws(new Exception());
driver.IntProperty = 3;
Assert.That(delegate { var i = driver.IntProperty; }, Throws.Exception);
}
Upvotes: 1
Views: 1641
Reputation: 27861
It is this line:
driver.IntProperty = 3;
that is causing your problem. What it does basically is configuring the getter to return the value 3 when it is invoked.
This is because IntProperty
is a Read/Write property. See this for more information.
Quoting from the link above:
Although you can explicitly specify the return value for a called property getter, there's an easier, more intuitive way to work with read/write properties. By default, any fakeable property that has both a set and get accessor behaves like you might expect. Setting a value and then getting the value returns the value that was set.
In addition, note that the behaviour you saw will change with FakeItEasy 2.0, due to the fix for
magic property get followed by another get returns different object when property type is not fakeable.
With that change, your two tests would've failed in about the same way - Property_Setter_Throws
would also fail, because using the getter for driver.IntProperty
would prime FakeItEasy to return the same return value instance in the future (it's setting up an automatic property rule).
And as a further bit of information that may help you in the future, you may enjoy using typesafe methods for setting up property behaviour:
A.CallTo(driver).Where(call => call.Method.Name == "get_IntProperty")
.Throws(new Exception());
can become
A.CallTo(() => driver.IntProperty).Throws(new Exception());
(and in FakeItEasy 2.0, there is a similar method for configuring property setters):
A.CallToSet(() => driver.IntProperty).Throws(new Exception());
Upvotes: 2