C# Extension Method Oddity during Unit Test - c#

Using Visual Studio 2008 / C# / VS Unit Testing.
I have a very straightforward extension method, that will tell me if an object is of a specific type:
public static bool IsTypeOf<T, O>(this T item, O other)
{
if (!(item.GetType() is O))
return false;
else
return true;
}
It would be called like:
Hashtable myHash = new Hashtable();
bool out = myHash.IsTypeOf(typeof(Hashtable));
The method works just fine when I run the code in debug mode or if I debug my unit tests. However, the minute I just run all the unit tests in context, I mysteriously get a MissingMethodException for this method. Strangely, another extension method in the same class has no problems.
I am leaning towards the problem being something other than the extension method itself. I have tried deleting temporary files, closing/reopening/clean/rebuilding the solution, etc. So far nothing has worked.
Has anyone encountered this anywhere?
Edit: This is a simplified example of the code. Basically, it is the smallest reproducible example that I was able to create without the baggage of the surrounding code. This individual method also throws the MissingMethodException in isolation when put into a unit test, like above. The code in question does not complete the task at hand, like Jon has mentioned, it is more the source of the exception that I am currently concerned with.
Solution: I tried many different things, agreeing with Marc's line of thinking about it being a reference issue. Removing the references, cleaning/rebuilding, restarting Visual Studio did not work. Ultimately, I ended up searching my hard drive for the compiled DLL and removed it from everywhere that did not make sense. Once removing all instances, except the ones in the TestResults folder, I was able to rebuild and rerun the unit tests successfully.
As to the content of the method, it was in unit testing that I discovered the issue and was never able to get the concept working. Since O is a RunTimeType, I do not seem to have much access to it, and had tried to use IsAssignableFrom() to get the function returning correctly. At this time, this function has been removed from my validation methods to be revisited at another time. However, prior to removing this, I was still getting the original issue that started this post with numerous other methods.
Post-solution: The actual method was not as complex as I was making it out to be. Here is the actual working method:
public static void IsTypeOf<T>(this T item, Type type)
{
if (!(type.IsAssignableFrom(item.GetType())))
throw new ArgumentException("Invalid object type");
}
and the unit test to verify it:
[TestMethod]
public void IsTypeOfTest()
{
Hashtable myTable = new Hashtable();
myTable.IsTypeOf(typeof(Hashtable));
try
{
myTable.IsTypeOf(typeof(System.String));
Assert.Fail("Type comparison should fail.");
}
catch (ArgumentException)
{ }
}

Usually, a MissingMethodException means that you are loading a different version of the dll to the one you referenced during build, and the actual dll you are loading (at run-time) doesn't have the method the compiler found (at compile-time).
Check that you haven't somehow got various versions of the dll referenced by different projects. It could be that when you run it in debug mode, some other code makes the correct dll load first, but when running in-context, this other code doesn't run - so the incorrect version loads instead.
This would apply doubly if the failing method was added recently, so might not be in the older version referenced.
If you are using full assembly versioning, you might be able to watch the debug output to see exactly which assembly loads.

I am speculating here.
Put a constraint on the method to see if that helps
Pseudocode
public static bool IsTypeOf(this T item, O other) Where T: object, O: Type
{
}
Also, which class is this method in?
EDIT: Is this class, part of the assembly which is being tested?

Related

How to test functions using File.Create() and File.Delete() methods in xunit?

I haven't been coding for too long, so apologies if this isn't articulated very well.
So, I've been trying to get my head around using constructors and IDisposable in order to write unit tests in xunit that test some functions relating to creating and deleting files. Initially I started writing tests without any sort of 'setup'/'teardown' equivalent, but I ran into the problem of tests passing on first run, but failing second time round as the file I was testing could be deleted had already been deleted in the previous instance of running the test! So, now I'm trying to include 'File.Create("file-path")', 'File.Delete("file-path")' type methods in my constructor, but find that my tests all break as soon as I incorporate one of these methods. This doesn't happen with 'Directory.CreateDirectory()', or 'Directory.Delete()'.
To exemplify, here is an example of the sort of thing I have been trying with the constructor...
public class SetUp : IDisposable
{
protected SetUp()
{
Directory.CreateDirectory(#"c:\Projects\Tests\Test");
File.Create(#"c:\Projects\Tests\test.txt");
}
public void Dispose()
{
Directory.Delete(#"c:\Projects\Tests\Test", true);
File.Delete(#"c:\Projects\Tests\test.txt");
}
}
This is necessary for the following test:
[Theory]
[InlineDataAttribute(#"c:\Projects\Tests\test3.txt")]
public void CanRemoveFile(string filePath)
{
//Assign
var myInstanceOfApphelper = new AppHelper();
bool fileExists = true;
//Act
myInstanceOfApphelper.RemoveFile(filePath);
fileExists = myInstanceOfApphelper.CheckFileExists(filePath);
//Assert
Assert.Equal(false, fileExists);
}
...as without this constructor part to create the file before running the tests, there will be no file at that location to delete next time I run the test, and it will fail. However, as soon as I include the line File.Create(#"c:\Projects\Tests\test.txt");, all of my tests break. The errors I am returned are all
"The process cannot access the file 'c:\Projects\Tests\test.txt'
because it is being used by another process."
but I can't understand this as most of the tests don't use 'c:\Projects\Tests\test.txt anyway!
Can anyone tell me why this won't work? How could I go about testing the creation and deletion of files in the xunit framework in such away that the tests consistently pass? Can you point out any obvious errors with the way I've written this?
The behaviour you describe means that you keep a handle on the file between two tests. I suggest you double check the way your setup and teardown works because it seems like you're doing it wrong (not calling them before and after each tests).
Bonus: I recommend not using the real file system while doing unit tests. There are in memory file systems which allows to completely clean your workspaces and be sure you are not bothered by the physical file system.
For instance check: https://github.com/bobvanderlinden/sharpfilesystem

How to quickly debug my code in isolation - internal, developer only, throw-away test

I'm looking for ways to quickly debug the code I've just written to see if it behaves correctly and all my assumptions are correct. I don't want to run the full system yet because parts of infrastructure to get to this code are missing. I use unit testing for it but I find it cumbersome. Is there anything better?
Objectives are:
Debug any code quickly without creating additional projects, applications etc.
Easily repeat debugging.
The test is for this specific purpose, might use fixed file paths, database connections, anything. Typically thrown away after getting things right.
Need to access internal members of my objects.
Accessing private member would be great benefit.
I'm fine with writing test functions directly in my object. Actually this would be preferred.
The dream way of doing it would be:
namespace Aaa
{
class SomeClass
{
public string Name { get; private set; }
public SomeClass(string name, int value)
{
this.Name = name;
InitializeSth();
}
public DoSomethingPublic()
{
// ...
}
private DoSomethingPrivate()
{
// ...
}
public static void TestThis() // <-- debug this
{
var obj = new SomeClass("a", 1); // <-- put breakpoint here
obj.DoSomethingPublic();
obj.DoSomethingPrivate();
}
}
}
This is possible in Java and is such a great thing. This allows for accessing private things too.
But I'm open to other options as well. Is there anything like this in VS2015?
What I have tried so far:
Immediate Window - I don't think it can be configured for such purpose
C# Interactive - this doesn't seem to support debugging. Or does it?
Unit testing - this is what I use now (with MSTest). But I find it very cumbersome, because:
I need to create new projects, or include references to MS testing assemblies
I need to make extra steps to access internal types and members, or change things to public (I don't like this).
Even more steps to access private members.
I mess with other tests if Unit Testing is used in the project.
Starting debugging again needs many clicks instead of sth+sth+F5.
There are some workarounds for some of these items, but in general the testing infrastructure seems to be made for different purposes and I always have a feeling I'm fighting against it.
I also found some information about Resharper having ability to debug any static function. But I don't want to use Resharper, mainly because of performance.
To debug one method without running the whole app, I often use the unit test in VS IDE, since it would not really impact our app's development.
I also got the method using the Resharper tool before: https://blog.jetbrains.com/dotnet/2015/08/28/run-configurations-debug-any-static-method-in-visual-studio-and-more/
In VS IDE, to debug the method directly without debugging/running the app, it really has no better suggestions than unit test project.
Of course, it also has other third party tool if you want to debug code without running the app:
http://www.linqpad.net/
Take a look at this answer: #if DEBUG vs. Conditional(“DEBUG”)
Basically you could use something like the following:
#if DEBUG
public void DoSomething() { }
#endif
public void Foo()
{
#if DEBUG
DoSomething();
#endif
}
Answering my own question - it seems I didn't evaluate Immediate Window enough.
It is possible to invoke any static method either using
Immediate Window (just type TestThis())
Command Window (type ?TestThis() or Debug.EvaluateStatement TestThis())
This even allows to invoke private static methods. The projects will be built before starting the method if they need to be and the method is executed in debugger, so it will stop at any breakpoint.
So summarizing: press Alt+Ctrl+I to get to the Immediate Window, type-in method name with parentheses and press Enter.
There are two disadvantages:
If the method is not in main class (one with Main method), you have to use full namespace and class name, for example MyCompany.MyApp.Logic.SomeClass.TestMethod() to run it
to start debugging again, you have to go to immediate window and recall last command with Up-Arrow, Enter. This is better than right-clicking on a test and selecting "Debug this test", but not optimal.
Please add an answer if you know anything better or some ways to make these two issues better. I looked for quite some time to find a keyboard shortcut to repeat last Immediate Window command, but cannot find one. I don't mark this answer as accepted for now, in case something better is posted.

Visual studio detecting unused return

I've just spent the best part of an hour trying to work out why some code appered to not be working. I was getting no compilation errors of any sort, and have tracked the bug down to calling a function and doing nothing with the return value. The code was a little more involved than the sample below as Class1 is immutable, but it still demonstrates the issue:
public class Class1
{
private int MyVal = 0;
public int GetMyVal()
{
return MyVal;
}
}
public void Tester(){
Class1 Instance = new Class1();
Instance.GetMyVal();
}
The function call to GetMyVal() is as technically useless as it is technically correct. As I say the code was more involved, but this is the core issue.
I'm slightly surprised that VS 2013 (For Web) fails to highlight the issue as clearly nothing is gained from calling GetMyVal. Is there some switches I'm missing to detect this sort of thing or is this beyond the scope of what Visual Studio can accomplish?
I doubt there is/are (m)any editors out there can can give you what you want.
VS will tell you if you have a variable you're not referencing (at least for Pro and Ultimate. Haven't used Web for 2012/2013). However within the scope of Class1, private int MyVal is being referenced within your GetMyVal function so it will not be marked as an unreferenced property.
It can often catch useless pieces of code but I don't see how you expect it to say that your previously initialized and referenced variable is not meaningful. It has no way of knowing that the property in Class1 isn't something you want to use/modify later.
Do correct me if I am misunderstanding your question
Side note: If you can figure out a way to make it do what you're after,might I suggest writing a plugin? Bear in mind that existing plugins like Resharper and FXCop add a world of functionality

MonoTouch mysteriously not aot-compiling methods and properties?

I have a strange problem where MonoTouch seems to be either not compiling methods or not able to find a compiled method it is instructed to call, and only on the device in the Release configuration - Debug builds are fine. I've tried reproducing it with a simpler code sample with no luck, so I doubt you will be able to see the behavior with the code below. But this is essentially what I'm doing:
using System;
using MonoTouch.UIKit;
public class MyClass
{
private UINavigationController _navController;
private UIViewControler _viewController;
public UINavigationController NavController
{
get
{
if (_navController == null)
{
if (_viewController == null)
{
_viewController = new UIViewController();
}
_navController = new UINavigationController(_viewController);
}
return _navController;
}
}
}
Then, in some other method...
public void SomeMethod()
{
MyClass myClass = new MyClass();
var navController = myClass.NavController; // <-- This is where it throws
}
The exception I get is the standard JIT compile message, saying that it attempted to JIT get_NavController(). I find this very strange, because there's no virtual generics, no LINQ, the linker is off, and nothing else that normally causes JITs seems to be involved. I've also verified that it will throw for other methods and properties defined on MyClass, but not the constructor or System.Object inherited methods. Reflection reveals that myClass.GetType().GetMembers() has a MemberInfo for everything I would expect. Yet, only for Release|iPhone, I can't access these methods or properties. The only logical conclusion I can come to is that the aot compilation step is missing them, and I don't know why that would happen at all, let alone only in the Release configuration.
My question is, what could be causing such a situation, and what is the next step to fixing it? I'm not even sure where to go from here on debugging this, or what to file a bug about, because I can't reproduce it out of the context of our (much) larger project.
Update: The exact exception text was requested.
System.ExecutionException: Attempting to JIT compile method
'MyNamespace.MyClass.get_NavController ()' while running with --aot-only
This doesn't look like something that can be solved here.
I suggest filing a bug, and attach the entire project if you're unable to make a smaller test case. You can file private bugs only Xamarin employees have access to if you don't want your project to be publicly visible.
Could you try to explicitly declare the variable
UINavigationController navController = myClass.NavController;
Alternatively, I wonder if this is at all associated with needing to wait for the UIViewController.ViewDidLoad method to be called as the internals of the class may not yet have been initialized?
Just shots in the dark here, I can't think of a reason why your code wouldn't work.

A product release changes its library name, how to be compatible with old and new?

We have a product that uses a Reference from a 3rd party supplier. With the release of their new product they have renamed this Reference to a new name.
What we want to do is have the one version of our application compiled so that it can run against both the old and new names of the library.
There is basically no change, only 1 method rename, between the parts of the library we use, but I have no idea how to develop our application to handle both.
If I have to we can branch the code to work with both, but I'd really like to have some sort of adapter that all calls go through that then dispatches to either the old or new.
Once I install the new application, it removes the old library, so the old code won't compile.
Any pointers on what I can try or how I can work around this issue?
Also, the application is developed in C# using Visual Studio 2005.
Look at Assembly Binding Redirection... You can redirect the old DLL references to the new one. You will need to write a wrapper method for the renamed method.. That's a real pain in the butt. I'm gonna spitball this off the top of my head, so I don't guarantee name accuracy or compilability, but you can consider it pseudo code...
private bool _useOldMethodName = false;
public void MethodAlias(string arg1)
{
if (_useOldMethodName)
{
Reference.OldFunctionName(arg1);
}
else
{
try
{
Reference.NewFunctionName(arg1);
}
catch (MethodNotFoundException mnfe)
{
_useOldMethodName = true;
}
}
}
Something like that. It's not ideal in any case.
I am curious, why can't you just always use the new reference? Just distribute the new reference DLL with your code, and you'll never have an issue...
I would suggest you the following steps:
Refactor your code to isolate the call to the library by having your own class which inherits from the library (no own methods for now - just one single place of change)
Use Reflection inside this single class to find out which of the two method is available. Cache the actual method to avoid a performance penalty when you call the library very frequently. The actual reflection will look like this:
Type type = Type.GetType(alien);
MemberInfo[] mbrInfoArray=type.GetMethods();
The method will be called using Invoke.

Categories