I am following this tutorial, https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-mstest
but I don't have the type PrivateObject available, so I am wondering if it would be possible to test private objects with a .net standard 2.0 project.
You can always use a reflection
ClassToTest obj = new ClassToTest();
Type t = typeof(ClassToTest);
FieldInfo f = t.GetField("field", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
f.SetValue(obj, "Don't panic");
t.InvokeMember("PrintField",
BindingFlags.InvokeMethod | BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Instance,
null, obj, null);
You should write a helper class for this, or else your tests will conatin a lot of identical code
P.S. Sample of code is from here
Private objects are accessible only within the body of the class, so in order to test them you must do one of the following:
make private objects public
or
implement public methods which will interact with these private objects
Related
I would like to be able to get a list of names of all the methods in a form (similar to the list obtained by pressing Alt+M).
I found the way to get only the names of the methods created by me.
Type methodInfoType = (typeof(Form_CreateNodes));
// Get the public methods.
MethodInfo[] arrayOfPublicMethodsNames = methodInfoType.GetMethods(
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
// Get the nonpublic methods.
MethodInfo[] arrayOfNonpublicMethodsNames = methodInfoType.GetMethods(
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
I have a static class with private functions, I want to get all functions except one. I tried using Ignorecase but i get an overload exception... I do it exactly like many examples online but I get an error and I dont know why...am I missing something?
//Example
static MethodInfo[] allFuncs ;
static Type myType = typeof(myClass);
allFuncs = myType.GetMethods("innerFunction",
BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Static);
If you want all methods except one with a particular name, you can use Enumerable.Where to filter:
allFuncs = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
.Where(method => !method.Name.Equals(
"innerFunction", StringComparison.OrdinalIgnoreCase));
I want to call Isolate.Verify with a list of property, using reflection.
var allProps = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.DeclaredOnly);
How can I use
Isolate.Verify.WasCalledWithAnyArguments(method)
It requires an Action, all I have are PropertyInfo.
Well, this was not an easy one, but hope this answers your question!
You can loop on all the properties in a given type and for each given property you perform a Verify.WasCalledWithAnyArguments.
I have written a simple unit test to demonstrate the concept. I assume there is a class TestSubject that contains the properties you want to verify were called with any arguments.
[TestMethod]
public void TestMethod1()
{
//Arrange
var fake = Isolate.Fake.Instance<TestSubject>();
//Act
//Getting/Setting desired properties of TestSubject class
//Assert
PropertyInfo[] propertyInfos =
fake.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly |
BindingFlags.SetProperty);
foreach (var propertyInfo in propertyInfos)
{
Isolate.Verify.WasCalledWithAnyArguments(() => propertyInfo.GetValue(fake, null));
}
}
Caveat:
In TDD practice, there is a common tendency to consider more than one assert per unit test as a"potentially" code smell. So I encourage to try to refactor your testing code and strategy to maybe avoid the reflection.
Otherwise the aforementioned should work!
Can anybody tell me what is this code doing:
PropertyInfo p = typeof(HttpRuntime).GetProperty("FileChangesMonitor",
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
object o = p.GetValue(null, null);
FieldInfo f = o.GetType().GetField("_dirMonSubdirs",
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
object monitor = f.GetValue(o);
MethodInfo m = monitor.GetType().GetMethod("StopMonitoring",
BindingFlags.Instance | BindingFlags.NonPublic);
m.Invoke(monitor, new object[] { });
How did the person get these reflection field names?
Effectively, the code is doing the equivalent of:
dynamic o = HttpRuntime.FileChangesMonitor;
dynamic monitor = o._dirMonSubdirs;
monitor.StopMonitoring();
The BindingFlags.NonPublic allow, through the use of reflection, accessing nonpublic fields. Without reflection, the above code would generate a compiler error.
The reflection field names can be obtained through a debugger, or types can be enumerated through reflection. For instance, to get all public and nonpublic static fields of a type X, you could use:
MemberInfo[] mi = typeof(X).GetType().FindMembers(MemberTypes.Property,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
(a, b) => true, // don't filter
null);
Note that using reflection to access nonpublic members is generally considered poor practice, since doing so relies on implementation mechanics that are not guaranteed and that are allowed to change from version to version and between implementations.
Question from a Reflection newbie. I have a method in a Windows Form:
private void handleOrderCode()
{
//...do stuff
}
Which I am trying to call in the following manner:
Type t = this.GetType();
MethodInfo mi = t.GetMethod("handleOrderCode");
if (mi != null) mi.Invoke(this, null);
I have confirmed that "this" is not null. The space where the string "handleOrderCode" has been hardcoded is to be replaced with a string variable when this works. However, at present "mi" is always null when it evaluates in the if statement in the final line.
So what am I doing wrong?
You need to specify binding flags:
using System.Reflection;
t.GetMethod("handleOrderCode", BindingFlags.Instance | BindingFlags.NonPublic)
Because overload without any flag means:
BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance
i.e. will not return any non-public (private, protected, etc) members.
The parameterless overload of Type.GetMethod only looks for public methods:
Searches for the public method with the specified name.
You need to specify an appropriate BindingFlags value to another overload instead:
MethodInfo method = t.GetMethod("handleOrderCode",
BindingFlags.Instance | BindingFlags.NonPublic);
Note that you need to specify "instance" or "static" here (or both), not just "non-public". If you want to look for public methods as well, you have to include that too.
Another alternative is just to make your method public :)
(Additionally, I'd suggest renaming it to HandleOrderCode to be more conventional, idiomatic C#.)
try:
Type t = this.GetType();
MethodInfo mi = t.GetMethod("handleOrderCode",
BindingFlags.NonPublic | BindingFlags.Instance);
if (mi != null) mi.Invoke(this, null);