Class method picks hidden base class property over new subclass property - c#

I'm trying to write a unit test for one of my classes that uses a base class from a third party library, but my first attempt is fragile as the tests depend on integration with texts managed by content managers.
First, a small repro. This will represent the third party base class I have to work with:
namespace ThirdPartyXyz
{
public class SomeFancyBaseClass
{
public SomeFancyBaseClass()
{
this.myMap = new Dictionary<string, string> { { "title", "Greatness" } };
}
public IReadOnlyDictionary<string, string> myMap { get; private set; }
}
}
Then I'm unit testing code along these lines:
namespace MyCorp
{
public class MyThing : ThirdPartyXyz.SomeFancyBaseClass
{
public string GetHeadline()
{
return "[" + this.myMap["title"] + "]";
}
}
}
With the following NUnit test method:
namespace MyCorp.UnitTestExperiments
{
[TestFixture]
public class MyThingTests
{
[Test]
public void GetHeadlineWillOutputBracketedResource()
{
var thing = new MyThing();
var result = thing.GetHeadline();
Assert.That(result, Is.EqualTo("[Greatness]"));
}
}
}
This is green, but will turn red if a content manager changes the "Greatness" value to something else. So I'm trying to mock / stub / fake the actual dictionary from the base class, but this is not straightforward because the third party library declares myMap's dictionary setter as private.
Here's what I've tried:
namespace MyCorp.UnitTestExperiments
{
[TestFixture]
public class MyThingTests
{
private class TestableMyThing : MyThing
{
public TestableMyThing(Dictionary<string, string> texts) { this.myMap = texts; }
public new IReadOnlyDictionary<string, string> myMap { get; private set; }
}
[Test]
public void GetHeadlineWillOutputBracketedResource()
{
var fakeTexts = new Dictionary<string, string> { { "title", "test text" } };
var thing = new TestableMyThing(fakeTexts);
var result = thing.GetHeadline();
Assert.That(result, Is.EqualTo("[test text]"));
}
}
}
However, this doesn't work: the test still fails. The GetHeadline method uses the hidden myMap property from SomeFancyBaseClass as opposed to the fake dictionary containing the "test text".
My goals / questions currently are two-fold. First, by now I'm curious how I (c/w)ould get my current approach to work. But second, I fear my way of making MyThing testable is not the best one, and would like to know if there's a way to avoid this situation altogether.

Three options:
Use reflection to access the seter of the dictionary
Second option, make your class more easily to stub:
public class MyThing : ThirdPartyXyz.SomeFancyBaseClass
{
public virtual new IReadOnlyDictionary<string, string> myMap;
{
get { return base.myMap; }
}
public string GetHeadline()
{
// this will use your 'virtual new myMap'!
return "[" + this.myMap["title"] + "]";
}
}
Now in your unit tests you can:
public class MyThingTestable : MyThing
{
public override IReadOnlyDictionary<string, string> myMap { get; set; }
}
and now you can set the myMap, and your class will use it (but note that the SomeFancyBaseClass class won't use it! It will use its myMap! Not very good!)
Third option: use Microsoft Fakes or similar product.

Related

Mock method return value with read only property

I wish to test a method which queries a third-party library. The library returns an object with a IReadOnlyCollection property.
There is no constructor to set the value of the property and the object has no interface for me to mock.
I have used Moq to mock the interface for the service that I call, but I can't create a mocked return value as I can't set the property.
public interface IHitService {
public Hit GetHit();
}
public class Hit {
public Hit() {
}
public IReadOnlyCollection<string> Result { get; }
}
public class TestingClass {
public void MyTest() {
Hit hit = new Hit() {
// cannot set this property
Result = new List<string>() { "hello","goodbye" };
}
Mock<IHitService> service = new Mock<IHitService>();
service.Setup(c => c.GetHit).Returns(hit);
}
}
What would be the best way for me to generate the return value to test my method? Wrapping the object with a new property to hide the base does not work.
You can use unit-test frameworks that allow you to change the behavior of a concrete object, for example in this case i used Typemock Isolator to try and solve your issue, it allows you to change the the return value of the result property so can "set" for your test without changing your code or adding extra code:
public void TestMethod1()
{
List<string> s = new List<string> { "sfas", "asfsa", "blbba" };
var hit = Isolate.Fake.NextInstance<Hit>();
Isolate.WhenCalled(() => hit.Result).WillReturnCollectionValuesOf(s);
}
In this test i mocked the Hit class and modified the return value of the Result property to a list of strings i created.
If you need to test a third-party library, it would be a better idea to create your own abstraction (interface) and rely on that for both testing and real code:
public interface IHitService
{
IHit GetHit();
}
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
In your application code, you can create a simple wrapper class that implements IHit by delegating to the concrete third-party class. Now you can test the interface by mocking it as needed.
In general, if you can't change 3rd party code, build an adapter to it and use your own abstraction :-
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
public interface IHitService
{
IHit GetHit();
}
public class HitAdapter : IHit
{
private Hit _hit;
public HitAdapter(Hit hit)
{
_hit = hit;
}
public IReadOnlyCollection<string> Result => _hit.Result;
}
public class TestingClass
{
public void MyTest()
{
var hitMock = new Mock<IHit>();
hitMock.Setup(c => c.Result).Returns<IReadOnlyCollection<string>>(x => new List<string>() {"hello", "goodbye"});
var service = new Mock<IHitService>();
service.Setup(c => c.GetHit()).Returns<IHit>(x => hitMock.Object);
}
}

Moq for single line multiple property code

I have these interfaces
public interface Interface1 { Interface2 Items {get;} }
public interface Interface2 { Guid? ApplicationTypeId { get; } }
public interface Interface3 { Class1 Item {get;} }
public interface Interface4 { Guid? ApplicationId { get; set; } }
A class inherits the first interface
public class Class1 : Interface1 {
public Interface2 Items { get; }
}
Another class which consists of few guids
public static class ContentTypeIds
{
public static Guid ContentGuid1 => new Guid("{11798e9d-a167-4cfc-8cfa-9a24fd6caf25}");
public static Guid ContentGuid2 => new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
}
I need to unit test the following property
private readonly Interface3 _interface3;
public Ticket Current
{
get
{
//This line is very complicated
Interface4 itemByContentType = _interface3.Item?.Items.GetItemByContentType(ContentTypeIds.ContentGuid2);
if ( itemByContentType?.ContentId != null )
return Get(itemByContentType.ContentId.Value);
return null;
}
}
My test class goes here
[Test]
public class TestClass {
var mock1 = new Mock<Interface1>();
var mock2 = new Mock<Interface2>();
var mock3 = new Mock<Interface3>();
mock1.SetupAllProperties();
mock2.SetupAllProperties();
mock3.SetupAllProperties();
}
The value for 'itemByContentType' goes null.
Could anyone help me to make it simple and testable as it is getting complicated to test this property? I'm using Moq. I will appreciate any help.
Thanks
I'm not an expert on Moq, but it looks like its SetupAllProperties method simply sets up all the properties to act like properties (i.e. the object it creates has a persistent member which can support GET/SET operation). If this isn't done, then as I understand it, the properties will still be available, but they'll always resolve to null. This is very handy when preparing the Mock objects, but on its own, though, that doesn't setup the properties with any sort of value.
I think what you should be doing is using Moq's SetupGet in conjunction with the Returns method to prepare the GET of the Items property with a specific value.
Here is some (simplified) sample code, to demonstrate this:
public interface IFoo { Guid? ApplicationId { get; set; } }
public interface IBar { IFoo Items { get; } }
class Program
{
static void Main(string[] args)
{
// SETUP
// Prepare mocks
Mock<IFoo> MockFoo = new Mock<IFoo>();
Mock<IBar> MockBar = new Mock<IBar>();
// Seting up properties allows us read/write Foo's ApplicationId
MockFoo.SetupAllProperties();
// The mocked Foo object should be what's returned when Items is requested
var expectedFoo = MockFoo.Object;
// Setup the Bar object to return that mocked Foo
MockBar.SetupGet(x => x.Items).Returns(expectedFoo);
// The value written here will be persistent due to SetupAllProperties
expectedFoo.ApplicationId = new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
// ACTION
// When the "Items" property is accessed, the IFoo we get should be what we mocked...
var actualFoo = MockBar.Object.Items;
// ... and we can read the value set to Foo's ApplicationId
var actualAppId = actualFoo.ApplicationId;
}
}

Is there an easy way to make an immutable version of a class?

Is there an easy way to make an instance immutable?
Let's do an example, I have a class holding a lots of data fields (only data, no behavior):
class MyObject
{
// lots of fields painful to initialize all at once
// so we make fields mutable :
public String Title { get; set; }
public String Author { get; set; }
// ...
}
Example of creation:
MyObject CreationExample(String someParameters)
{
var obj = new MyObject
{
Title = "foo"
// lots of fields initialization
};
// even more fields initialization
obj.Author = "bar";
return obj;
}
But now that I have fully created my object, I don't want the object to be mutable anymore (because the data consumer will never need to change the state), so I would like something like that List.AsReadOnly:
var immutableObj = obj.AsReadOnly();
But if I want this behavior, I need to make another class that have exactly the same fields but without setter.
So is there any automatic way to generate this immutable class ? Or another way to allow mutability during creation but immutable once initialized ?
I know that fields can be marked as "readonly", but the object will be initialized outside of the class, and passing all fields as constructor parameters seems like a bad idea (too much parameters).
No, there is no easy way to make any type immutable, especially not if you want "deep" immutability (i.e. where no mutable object can be reached through the immutable object). You will have to explicitly design your types to be immutable. The usual mechanisms to make types immutable are these:
Declare (property-backing) fields readonly. (Or, starting with C# 6 / Visual Studio 2015, use read-only auto-implemented properties.)
Don't expose property setters, only getters.
In order to initialize (property-backing) fields, you must initialize them in the constructor. Therefore, pass the (property) values to the constructor.
Don't expose mutable objects, such as collections based on mutable-by-default types (like T[], List<T>, Dictionary<TKey,TValue>, etc.).
If you need to expose collections, either return them in a wrapper that prevents modification (e.g. .AsReadOnly()), or at the very least return a fresh copy of the internal collection.
Use the Builder pattern. The following example is too trivial to do the pattern justice, because it's usually recommended in cases where non-trivial object graphs need to be created; nevertheless, the basic idea is something like this:
class FooBuilder // mutable version used to prepare immutable objects
{
public int X { get; set; }
public List<string> Ys { get; set; }
public Foo Build()
{
return new Foo(x, ys);
}
}
class Foo // immutable version
{
public Foo(int x, List<string> ys)
{
this.x = x;
this.ys = new List<string>(ys); // create a copy, don't use the original
} // since that is beyond our control
private readonly int x;
private readonly List<string> ys;
…
}
Hmm I will enumerate my first thought on this...
1. Use internal setters if your only worry is manipulation outside of your assembly. internal will make your properties available to classes in the same assembly only. For example:
public class X
{
// ...
public int Field { get; internal set; }
// ...
}
2. I don't agree that it's necessarily a bad idea to have lots of parameters in your constructor.
3. You could generate another type at runtime that is a read-only version of your type. I can elaborate on this, but personally I think this is overkill.
Best, Iulian
As another solution you can use Dynamic Proxy. Alike approach was used for Entity Framework http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx. Here is example how you can do it using Castle.DynamicProxy framework. This code is based on original example from Castle Dynamic proxy (http://kozmic.net/2008/12/16/castle-dynamicproxy-tutorial-part-i-introduction/)
namespace ConsoleApplication8
{
using System;
using Castle.DynamicProxy;
internal interface IFreezable
{
bool IsFrozen { get; }
void Freeze();
}
public class Pet : IFreezable
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
public virtual bool Deceased { get; set; }
bool _isForzen;
public bool IsFrozen => this._isForzen;
public void Freeze()
{
this._isForzen = true;
}
public override string ToString()
{
return string.Format("Name: {0}, Age: {1}, Deceased: {2}", Name, Age, Deceased);
}
}
[Serializable]
public class FreezableObjectInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
IFreezable obj = (IFreezable)invocation.InvocationTarget;
if (obj.IsFrozen && invocation.Method.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
{
throw new NotSupportedException("Target is frozen");
}
invocation.Proceed();
}
}
public static class FreezableObjectFactory
{
private static readonly ProxyGenerator _generator = new ProxyGenerator(new PersistentProxyBuilder());
public static TFreezable CreateInstance<TFreezable>() where TFreezable : class, new()
{
var freezableInterceptor = new FreezableObjectInterceptor();
var proxy = _generator.CreateClassProxy<TFreezable>(freezableInterceptor);
return proxy;
}
}
class Program
{
static void Main(string[] args)
{
var rex = FreezableObjectFactory.CreateInstance<Pet>();
rex.Name = "Rex";
Console.WriteLine(rex.ToString());
Console.WriteLine("Add 50 years");
rex.Age += 50;
Console.WriteLine("Age: {0}", rex.Age);
rex.Deceased = true;
Console.WriteLine("Deceased: {0}", rex.Deceased);
rex.Freeze();
try
{
rex.Age++;
}
catch (Exception ex)
{
Console.WriteLine("Oups. Can't change that anymore");
}
Console.WriteLine("--- press enter to close");
Console.ReadLine();
}
}
}
I would suggest having an abstract base type ReadableMyObject along with derived types MutableMyObject and ImmutableMyObject. Have constructors for all the types accept a ReadableMyObject, and have all the property setters for ReadableMyObject call an abstract ThrowIfNotMutable method before updating their backing field. Additionally, have ReadableMyObject support a public abstract AsImmutable() method.
Although this approach will require writing some boilerplate for each property of your object, that will be the extent of the required code duplication. The constructors for MutableMyObject and ImmutableMyObject will simply pass the received object to the base-class constructor. Class MutableMyObject should implement ThrowIfNotMutable to do nothing, and AsImmutable() to return new ImmutableMyObject(this);. Class ImmutableByObject should implement ThrowIfNotMutable to throw an exception, and AsImmutable() to return this;.
Code which receives a ReadableMyObject and wants to persist its contents should call its AsImmutable() method and store the resulting ImmutableMyObject. Code which receives a ReadableMyObject and wants a slightly-modified version should call new MutableMyObject(theObject) and then modify that as required.
You kind of hinted at a way in your question, but I'm not sure if this is not an option for you:
class MyObject
{
// lots of fields painful to initialize all at once
// so we make fields mutable :
public String Title { get; protected set; }
public String Author { get; protected set; }
// ...
public MyObject(string title, string author)
{
this.Title = title;
this.Author = author;
}
}
Due to the constructor being the only way of manipulating your Author and Title, the class is in effect immutable after construction.
EDIT:
as stakx mentioned, I too am a big fan of using builders - especially because it makes unit testing easier. For the above class you could have a builder such as:
public class MyObjectBuilder
{
private string _author = "Default Author";
private string _title = "Default title";
public MyObjectBuilder WithAuthor(string author)
{
this._author = author;
return this;
}
public MyObjectBuilder WithTitle(string title)
{
this._title = title;
return this;
}
public MyObject Build()
{
return new MyObject(_title, _author);
}
}
This way you can construct your objects with default values, or override them as you please, but MyObject's properties can't be changed after construction.
// Returns a MyObject with "Default Author", "Default Title"
MyObject obj1 = new MyObjectBuilder.Build();
// Returns a MyObject with "George R. R. Martin", "Default Title"
MyObject obj2 = new MyObjectBuilder
.WithAuthor("George R. R. Martin")
.Build();
If you ever need to add new properties to your class, it's much easier to go back to your unit tests that consume from a builder rather than from a hardcoded object instantiation (i don't know what to call it, so pardon my terms).
Well, if you have too many parameters and you dont want to do constructors with parameters....here is an option
class MyObject
{
private string _title;
private string _author;
public MyObject()
{
}
public String Title
{
get
{
return _title;
}
set
{
if (String.IsNullOrWhiteSpace(_title))
{
_title = value;
}
}
}
public String Author
{
get
{
return _author;
}
set
{
if (String.IsNullOrWhiteSpace(_author))
{
_author = value;
}
}
}
// ...
}
Here's another option. Declare a base class with protected members and a derived class that redefines the members such that they are public.
public abstract class MyClass
{
public string Title { get; protected set; }
public string Author { get; protected set; }
public class Mutable : MyClass
{
public new string Title { get { return base.Title; } set { base.Title = value; } }
public new string Author { get { return base.Author; } set { base.Author = value; } }
}
}
Creating code will use the derived class.
MyClass immutableInstance = new MyClass.Mutable { Title = "Foo", "Author" = "Your Mom" };
But for all cases where immutability is expected, use the base class:
void DoSomething(MyClass immutableInstance) { ... }

Stub a readonly property in a baseclass

I have a class like this:
public class Customer : CustomerBase
{
// internals are visible to test
internal string GenString()
{
// this actually composes a number of different properties
// from the parent, child and system properties
return this.InfoProperty.Name + DateTime.Now.ToString() + "something else";
}
}
// this class is in a 3rd party library, but from metadata it looks like this
public class CustomerBase
{
public Info InfoProperty { get; }
}
My test looks something like this:
public class Tests
{
public void MyTest()
{
using (ShimsContext.Create())
{
// Arrange
/* I shim datetime etc. static calls */
Fakes.StubCustomer c = new Fakes.StubCustomer()
{
InfoProperty = new Info("Name") // <- Error here because it's readonly
};
// Act
string result = c.GenString();
// Assert
Assert.AreEqual(result, "whatnot");
}
}
}
So my question is, how can I stub/shim the readonly property so that I can test this function?
What about wrapping this getter in an ad hoc virtual method that could be overrided by a mock?
Eg:
public class Customer : CustomerBase
{
// internals are visible to test
internal string GenString()
{
// this actually composes a number of different properties
// from the parent, child and system properties
return InfoPropertyNameGetter() + DateTime.Now.ToString() + "something else";
}
public virtual string InfoPropertyNameGetter(){
retrn this.InfoProperty.Name;
}
}
Mock<Customer> mock = new Mock<Customer>();
mock.Setup(m => m.InfoPropertyNameGetter()).Returns("My custom value");
It would look a bit like the Introduce Instance Delegator pattern described in Working effectively with legacy code

What is the best way to define a static property which is defined once per sub-class?

I wrote the following console app to test static properties:
using System;
namespace StaticPropertyTest
{
public abstract class BaseClass
{
public static int MyProperty { get; set; }
}
public class DerivedAlpha : BaseClass
{
}
public class DerivedBeta : BaseClass
{
}
class Program
{
static void Main(string[] args)
{
DerivedBeta.MyProperty = 7;
Console.WriteLine(DerivedAlpha.MyProperty); // outputs 7
}
}
}
As this console app demonstrates, the MyProperty property exists once for all instances of BaseClass. Is there a pattern to use which would allow me to define a static property which will have allocated storage for each sub-class type?
Given the above example, I would like all instances of DerivedAlpha to share the same static property, and all instances of DerivedBeta to share another instance of the static property.
Why am I trying to do this?
I am lazily initializing a collection of class property names with certain attributes (via reflection). The property names will be identical for each derived class instance, so it seems wasteful to store this in each class instance. I can't make it static in the base class, because different sub-classes will have different properties.
I don't want to replicate the code which populates the collection (via reflection) in each derived class. I know that one possible solution is to define the method to populate the collection in the base class, and call it from each derived class, but this is not the most elegant solution.
Update - Example of what I'm doing
At Jon's request, here's an example of what I'm trying to do. Basically, I can optionally decorate properties in my classes with the [SalesRelationship(SalesRelationshipRule.DoNotInclude)] attribute (there are other attributes, this is just a simplified example).
public class BaseEntity
{
// I want this property to be static but exist once per derived class.
public List<string> PropertiesWithDoNotInclude { get; set; }
public BaseEntity()
{
// Code here will populate PropertiesWithDoNotInclude with
// all properties in class marked with
// SalesRelationshipRule.DoNotInclude.
//
// I want this code to populate this property to run once per
// derived class type, and be stored statically but per class type.
}
}
public class FooEntity : BaseEntity
{
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_A { get; set; }
public int? Property_B { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_C { get; set; }
}
public class BarEntity : BaseEntity
{
public int? Property_D { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_E { get; set; }
public int? Property_F { get; set; }
}
Desired end result
Accessing FooEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_A",
"Property_C"
}
Accessing BarEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_E"
}
Two possible approaches:
Use attributes; decorate each subclass with an attribute, e.g.
[MyProperty(5)]
public class DerivedAlpha
{
}
[MyProperty(10)]
public class DerivedBeta
{
}
That only works when they're effectively constants, of course.
Use a dictionary:
var properties = new Dictionary<Type, int>
{
{ typeof(DerivedAlpha), 5) },
{ typeof(DerivedBeta), 10) },
};
EDIT: Now that we have more context, Ben's answer is a really good one, using the way that generics work in C#. It's like the dictionary example, but with laziness, thread-safety and simple global access all built in.
Jon has a good solution as usual, although I don't see what good attributes do here, since they have to be explicitly added to every subtype and they don't act like properties.
The Dictionary approach can definitely work. Here's another way to do that, which explicitly declares that there will be one variable per subclass of BaseEntity:
class FilteredProperties<T> where T : BaseEntity
{
static public List<string> Values { get; private set; }
// or static public readonly List<string> Values = new List<string>();
static FilteredProperties()
{
// logic to populate the list goes here
}
}
The drawback of this is that it's rather difficult to pair with a GetType() call such as you might use in methods of BaseEntity. A Dictionary, or wrapper thereto which implements lazy population, is better for that usage.
I just recently needed this same thing and came across this question. I think Jon's and Fried's ideas to use a Dictionary are on the right track but don't quite hit what I was looking for so I thought I'd show my own complete and very easy to extend implementation.
public class TypeStaticProperty<T>
{
T _defaultValue;
Dictionary<Type, T> _values = new Dictionary<Type, T>();
public TypeStaticProperty(T defalutValue = default)
{
_defaultValue = defalutValue;
}
public T Get(object caller)
{
lock (_values)
{
if (_values.TryGetValue(caller?.GetType(), out T val))
return val;
else
return _defaultValue;
}
}
public void Set(object caller, T val)
{
lock (_values)
_values[caller?.GetType()] = val;
}
}
And to demonstrate:
class TestBaseClass
{
static TypeStaticProperty<int> _property = new TypeStaticProperty<int>();
public int Property
{
get => _property.Get(this);
set => _property.Set(this, value);
}
}
class TestClass1 : TestBaseClass
{
}
class TestClass2 : TestBaseClass
{
}
class Program
{
static void Main(string[] args)
{
TestClass1 test1a = new TestClass1();
TestClass1 test1b = new TestClass1();
test1a.Property = 1;
test1b.Property = 2;
TestClass2 test2a = new TestClass2();
TestClass2 test2b = new TestClass2();
test2a.Property = 3;
test2b.Property = 4;
Console.WriteLine($"test1a.Property = {test1a.Property}");
Console.WriteLine($"test1b.Property = {test1b.Property}");
Console.WriteLine($"test2a.Property = {test2a.Property}");
Console.WriteLine($"test2b.Property = {test2b.Property}");
}
}
Output:
test1a.Property = 2
test1b.Property = 2
test2a.Property = 4
test2b.Property = 4
So while you still need a class instance to access and set the property, the value will always be the same across all instances of that precise type. (This includes generics too; Foo<int> will be seen as a different type than Foo<string>). This has the huge advantage over Fried's example in that you don't need to know at compile time the precise type whose "static" value you're looking for when accessing or setting.
PS - For full disclosure, this was heavily inspired by the WPF source code, which uses a very similar pattern for DependencyProperty's and all kinds of other internal bells and whistles designed to improve performance and reduce memory footprint.

Categories