PrivateObject does not find property - c#

I have a structure which looks basicly like this:
abstract class A
{
protected string Identificator { get; set; }
private void DoSomething()
{
// ...
DoSomethingSpecific();
}
protected abstract void DoSomethingSpecific();
}
Because of the complexity I need do unit tests the DoSomething method to be sure it works allways in the same way. Thats why I created following stub.
public class AStub : A
{
protected override void DoSomethingSpecific()
{
// nothing to do
}
}
I use the PrivateObject class to access the methods and properties of class A be instantiating class AStub. This worked for a while and for some reason crashes now whenever I try to access either the property or the method.
following code for testing:
var sut = new CommonIodAdapterImpl();
var accessor = new PrivateObject(sut);
accessor.SetProperty("Identificator", "blablub");
accessor.Invoke("DoSomething", null);
// assert...
The exception which is thrown is a MissingMethodException telling me that the propertie or method was not found. But when I debug and check the hierachy every seems to be right inclduing the spelling.
Thank you for your help.

You need to set the PrivateType argument to your base class to access the private members at that level.
var accessor = new PrivateObject(sut, new PrivateType(typeof(A)));

Shouldn't that be "public class AStub : A"?
To resolve the missing method exception just compile everything(!) once more. Either you get some compiler error telling you what's wrong or the error will vanish.
If it still doesn't work, check if you don't have multiple copies of the assemblies (including GAC!) and watch in the Deboug-Out-Window if it loads the assemblies from the correct path.

I just tried something similar, i assmued it's because the property is protected rather than private.
I created my own accessor in my test assembly
public class AAccessor : A
{
// use this instead of Identificator
public string IdentificatorAccessor
{
get { return this.Identificator; }
set { this.Identificator = value; }
}
// test this method in your unit test
public void DoSomethingAccessor()
{
this.DoSomethingSpecific()
}
// need this to satisfy the abstract class
protected override void DoSomethingSpecific()
{
// do nothing here
}
}

public class BaseClass
{
private int _fieldToSet;
...
}
public class DerivedClass : BaseClass
{
...
}
// Unit Test Code
public void Test()
{
DerivedClass d = new DerivedClass();
PrivateObject privObj = new PrivateObject(d, new PrivateType(typeof(BaseClass));
privObj.SetFieldOrProperty("fieldToSet", 8675309);
...
}

Related

How to get the name of the instance disposed by using reflection

I am building some integration tests for my database stored procedures.
I have setup an xUnit project and implemented Fixture pattern. To show you:
public class MyTableTest : IClassFixture<DatabaseFixture>
{
public MyTableTest()
{
//DO SOMETHING
}
[Fact]
public void Test()
{
//DO SOMETHING
}
}
And:
public class DatabaseFixture : IDisposable
{
public void Dispose()
{
// ... clean up test data from the database ...
}
}
This DatabaseFixture is something that will be shared among all of my test classes. Why? Because I want some common logic happening at the end of every test, such as cleanup.
Point is that I need to know which table to clean, which in my example would be MyTable. Such information I would retrieve by using reflection when the Dispose method will run against the instance of MyTableTest being disposed . How can I achieve this? Is it even possible (and correct) trying to achieve this? Thanks in advance.
You can have a TableName property in the DatabaseFixture class. Then receive an instance of the class in constructor of your test classes and set that TableName property. Later you can use it in dispose to do some cleanup.
public class MyTableTest : IClassFixture<DatabaseFixture>
{
DatabaseFixture databaseFixture;
public MyTableTest(DatabaseFixture databaseFixture)
{
this.databaseFixture = databaseFixture;
databaseFixture.TableName = "MyTable";
}
[Fact]
public void Test()
{
}
}
public class DatabaseFixture : IDisposable
{
//...
public string TableName { get; set; }
//...
public void Dispose()
{
// Cleanup based on TableName
}
}
To learn more about sharing context in xUnit, take a look at:
Shared Context between Tests
Comparing xUnit.net to other frameworks
You can use custom attributes to attach any arbitrary data to your derived Fixture class.
For example
you can create a TableNameAttribute like this:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class TableNameAttribute : Attribute
{
public string Name { get; }
public TableNameAttribute(string name)
{
this.Name = name;
}
}
you can apply this attribute to your derived fixture class:
[TableName("MyTable")]
public class MyTableFixture : DatabaseFixture { }
you can use that fixture class inside your test
public class MyTableTest : IClassFixture<MyTableFixture>
{
[Fact]
public void Test()
{
//DO SOMETHING
}
}
Finally this is how you can retrieve the Name from the Dispose method:
public abstract class DatabaseFixture : IDisposable
{
...
public void Dispose()
{
var attribute = this.GetType().GetCustomAttribute(typeof(TableNameAttribute));
if (attribute is TableNameAttribute tableNameAttr)
Console.WriteLine(tableNameAttr.Name);
}
}
Is it even possible (and correct) trying to achieve this?
No. Reflection cannot tell type T in what context T is used; reflection only sees T's declaration.
More specific to your situation, reflection cannot tell type DatabaseFixture that it is being used as a type parameter of generic interface IClassFixture in the declaration of MyTableTest. In other words, for this set of declarations,
class A { }
class B <T> { }
class C : B<A> { }
A cannot reflectively determine that it is used in C's declaration, but C can know about its usage of A:
typeof(C)
.BaseType // B
.GetGenericArguments()[0] // A
How can I achieve this?
Depending on how you are using DatabaseFixture, you could get the calling test class using the StackTrace (if you are really bent on using reflection). Here is a simple example:
public class DisposableObject : System.IDisposable
{
public void Dispose()
{
var stack = new System.Diagnostics.StackTrace();
// This will log the name of the class that instantiated and disposed this.
System.Console.WriteLine(stack.GetFrame(1).GetMethod().DeclaringType.Name);
return;
}
}
If your DatabaseFixture is not called directly from your test class, you will either have to know the offset to pass to GetFrame(int), or you will need to search each frame until you find the first DeclaringType that matches your requirements (e.g., BaseType is IClassFixture with Generic Argument DatabaseFixture), something like this:
System.Type testClassType = new StackTrace()
.GetFrames()
.Where(f =>
{
System.Type baseType = f.GetMethod().DeclaringType.BaseType;
return typeof(IClassFixture<DatabaseFixture>).IsAssignableFrom(baseType);
})
.FirstOrDefault() // First matching result (assuming you found any)
?.GetMethod() // Get the reflected Method
.DeclaringType; // Get the type (e.g. class) that declares this method.
string tableName = testClassType.Name.Replace("Test", "");
Otherwise, you will need to set the table name manually, as suggested by Reza and Peter.

How to use Activator.CreateInstance() to call an override C#

I am looking to find the proper way to call a overridden function of an inherited class using the Activator.CreateInstance() function. I am doing this so that I can call a specific function of a derived class based on a string object, such that the string determines which derived class object will be created and have its function called. Something like this but I do not know how to do it properly or if there is a better way than using Activator.
public class Test
{
public virtual void DefaultCalibration()
{
//Do nothing
}
}
public class EasyTest : Test
{
public override void DefaultCalibration()
{
//Do one thing
}
}
public class HardTest : Test
{
public override void DefaultCalibration()
{
//Do another thing
}
}
public class Tester
{
public void main()
{
string testName = "";
// ...
// ... Do some stuff to get a string of the name of the class, ie testName = "HardTest";
// ...
Type type = Type.GetType(testName);
object instance = Activator.CreateInstance(type);
((Test)instance).DefaultCalibration(); //this line doesn't call the derived function
}
}
I want it so that the derived class' override function is called instead of the base class function.
The intent being that if my string is "HardTest", then it would essentially look like
((HardTest)instance).DefaultCalibration();
but if it was "EasyTest" then it would look like
((EasyTest)instance).DefaultCalibration();

Substitute read only property in partially mocked object

I'm testing an MVC controller which relies on a value returned from a read-only property on the base class.
The getter for this property throws an exception when it is called as it is relies on a HttpContext (and other nasty stuff) which I would rather avoid mocking.
This is what I've tried so far:
controller = Substitute.ForPartsOf<MyController>(
Substitute.For<SomeDependency>(),
);
controller.UserInfo.Returns(new UserInfo());
Yet this throws an exception as soon as UserInfo is accessed.
Property on base class is:
public UserInfo UserInfo
{
get
{
// HttpContext dependent stuff
}
}
I've tried setting the base class property to virtual but then I get a Castle proxy exception.
I think you may be having another problem. NSubstitute is capable of handling substitution 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 your use of ForPartsOf I don't think it is possible to override a property this way, since there is no way of informing NSubstitute that we don't want it to call the base code. That's why the documentation mentions that partial sub are not recommended
You could change the base class in order to return the value of a virtual function; this virtual function would then be substituted. No signature change for the callers. Although this is a hack you would 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);

Get custom attribute from SubClass in BaseClass (C# .NET 4.0)

Ok, edited the code for clarification:
Question: How can I access the attribute [MyAttr("...")] in TestClassOne/Two from BaseClass.TheAttribute...?
All classes except TestClassOne/Two will be compiled in to my "core" and delivered as a dev-platform to a customer.
The TestClassOne/Two is developed by the customer, so there can be no knowledge of the TestClassOne/Two in the "core".
Code below is compiled into "core" and delivered to customer as dll.
[TestMethod()]
public void AttrTest()
{
var one = new TestClassOne();
var attrOne = one.MyTestProperty.TheAttribute;
var two = new TestClassTwo();
var attrTwo = two.MyTestProperty.TheAttribute;
}
public class MyAttr : Attribute
{
private string _test;
public MyAttr(string test)
{
this._test = test;
}
}
public class BaseClass
{
public string TheAttribute
{
get {
// Here I would like to get the "[MyAttr("...")]" from the classes in the bottom
return null;
}
}
}
public class SubClass : BaseClass
{
}
Code below is developed by customer (using my dll's)
public class TestClassOne
{
[MyAttr("Attribute one")]
public SubClass MyTestProperty = new SubClass();
}
public class TestClassTwo
{
[MyAttr("Attribute two")]
public SubClass MyTestProperty = new SubClass();
}
You can get directly from type Test:
var result = typeof (Test)
.GetField("MyTest", BindingFlags.Public | BindingFlags.Instance)
.GetCustomAttribute<MyAttr>();
Edit 3:
You can walk the call stack, looking for a relevant attribute in a relevant member in a relevant class. Try this:
public class MyAttr : Attribute
{
private string _test;
public MyAttr(string test)
{
this._test = test;
}
public string getAttr()
{
return _test;
}
}
public class BaseClass
{
private string theString;
public BaseClass()
{
StackTrace callStack = new StackTrace();
for ( int i = 0; i < callStack.FrameCount; i++ )
{
Type t = callStack.GetFrame(i).GetMethod().DeclaringType;
foreach ( MemberInfo m in t.GetMembers().Where(x => typeof(BaseClass).IsAssignableFrom(x.Type)) )
{
foreach ( var z in m.GetCustomAttributes(typeof(MyAttr)) )
{
MyAttr theAttr = z as MyAttr;
if ( z!= null )
{
theString = z.getAttr();
return;
}
}
}
}
}
public string Test
{
get {
return theString;
}
}
}
This requires that your customer always initializes the SubClass member inside the class that declares it. If they start deriving TestClassOne or have it and TestClassTwo derive from a common class that initializes the member, this code will break.
With clever use of reflection, you can expand the above code to cover more use cases, but that's beyond the scope of this question.
Edit 2:
No. I'm sorry, but what you're trying to do isn't possible. There's no "normal" way for an instance of SubClass to know if it's being declared in a member field of some other object, or in an element in an array or in a temporary variable in the stack, or whatever. As such, there's no way for that instance to access the attributes of the member field that's declaring it.
(I suppose you might want to try to access the garbage collector to find out where in memory the this object lives, but that's probably way beyond the scope of this problem, and in any case, not something I know how to do.)
I suspect your problem lies elsewhere entirely. Maybe you need to require your customer to make TestClassOne and TestClassTwo derive from a common abstract class. Maybe they need to derive from BaseClass themselves. Maybe you need to add parameters to the constructor. Maybe you need to provide a different interface altogether. We can't know unless you provide more information on your specific business requirements.
Edit:
To access the attributes declared on the MyTest member, try something along these lines:
public class BaseClass
{
public string Test
{
get {
var attr = typeof(Test).GetMembers().Where(x => x.Type == this.GetType()).First().GetCustomAttributes(true);
return null;
}
}
}
This will search class Test for a member with the same type as this and look for attributes on that member.
(I don't have my Visual Studio here, to check the exact Where syntax, but it should be pretty close to that...)
Original Answer:
Your attribute is declared on the MyTest member of class Test. But, you're doing GetCustomAttributes on class SubClass itself.
Try this:
[MyAttr("apa")]
public class SubClass : BaseClass
{
}
public class Test
{
public SubClass MyTest = new SubClass();
}
Should get you what you want.

Accessing a class protected field without modifying original class

I am using some 3rd party library that exposes some type (returned by a method).
This type has some protected fields i am interested in, however i am not able to use them since their visibility is protected.
Here is a simplification of the problem:
public class A
{
protected object Something;
public A Load()
{
return new A();
}
}
public class ExtendedA : A
{
public void DoSomething()
{
// Get an instance.
var a = Load();
// Access protected fields (doesn't compile).
a.Something = ....
}
}
Is there any easy way to achieve this?
Description
You can access the Field using this.Something because your class is derived from class A.
If you want to create a instance of the class A, not your derived class, you can only access the field using reflection.
Sample using Reflection
public class ExtendedA : A
{
public void DoSomething()
{
// Get an instance.
var a = Load();
//get the type of the class
Type type = a.GetType();
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
// get the field info
FieldInfo finfo = type.GetField("Something", bindingFlags);
// set the value
finfo.SetValue(a, "Hello World!");
// get the value
object someThingField = finfo.GetValue(a);
}
}
More Information
Accessing Protected Properties and Fields with Reflection
That's because you actually can't access it.
You can't call protected methods on any instance other than this (or base).
Just because your code happens to be in a descendant of A does not mean that this rule suddenly changes.
Eric Lippert has an excellent explanation in his blog:
http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/why-can-t-i-access-a-protected-member-from-a-derived-class.aspx
By inheriting from A you create a new class (ExtendedA) which has a member Something that you can access from within ExtendedA
public class ExtendedA : A
{
public void DoSomething()
{
// works fine
this.Something = ....
}
}
Inheriting does not give you the ability to reach into an instance of A to change Something
public class ExtendedA : A
{
public void DoSomething()
{
var a = new A();
// access level error
a.Something = ....
}
}
If you want to use the Something value you can do so within ExtendedA but only on the ExtendedA instance's own copy of Something.
hth,
Alan.

Categories