Replace a read-only property in a partially mocked object

I am testing an MVC controller that relies on a value returned from a read-only property in a base class.

The getter for this property throws an exception when it is called, since it relies on HttpContext (and other unpleasant things), which I would prefer to avoid ridicule.

This is what I have tried so far:

 controller = Substitute.ForPartsOf<MyController>( Substitute.For<SomeDependency>(), ); controller.UserInfo.Returns(new UserInfo()); 

However, this throws an exception as soon as user access is accessed.

Property in the base class:

 public UserInfo UserInfo { get { // HttpContext dependent stuff } } 

I tried setting the base class property to virtual, but then I got Castle proxy exception.

+6
source share
1 answer

I think you may have another problem. NSubstitute is able to handle the replacement of virtual properties. Here is a small program that illustrates

 public class SubstitutedClass { public virtual int SubstitutedProperty { get { throw new InvalidOperationException(); } } } internal class Program { private static void Main(string[] args) { var test2 = Substitute.For<SubstitutedClass>(); test2.SubstitutedProperty.Returns(10); Console.WriteLine(test2.SubstitutedProperty); } } 

EDIT: Regarding the use of ForPartsOf , I donโ€™t think it is possible to override a property this way, since there is no way to tell NSubstitute that we donโ€™t want it to call the base code. This is why the documentation mentions that partial sub is not recommended.

You can change the base class to return the value of a virtual function; this virtual function will be replaced. No signature change for callers. Although this is a hack, you will get what you need.

 public class SubstitutedClass { public virtual int SubstitutedProperty { get { return InnerValue(); } } public virtual int InnerValue() { throw new InvalidOperationException(); } } var test2 = Substitute.ForPartsOf<SubstitutedClass>(); test2.When(t => t.InnerValue()).DoNotCallBase(); test2.InnerValue().Returns(10); 
+5
source

All Articles