I am trying to run some unit tests for a project that, unfortunately, has a high level of block interdependence. Currently, many of our classes refer to the UserIdentity user object to define authentication, but this object has many internal hoops that I would just as quickly avoid when trying to test individual module functionality.
To get around some of this, I am trying to create a โmockโ version of this UserIdentity that can be connected to a more rigid controlled environment.
In short, we have a UserIdentity class with several read-only public properties and a static CurrentIdentity ( IIdentity ) tag. I can get around almost everything using the IIdentity โlayoutโ, but I run into a wall when I reach the point at which CurrentIdentity is used as UserIdentity .
This is a pretty simple method:
internal static UserIdentity GetCurrentIdentity() { UserIdentity currentIdentity = ApplicationContext.User.Identity as UserIdentity; return currentIdentity; }
I set my layout to create a member of type UserIdentity and then do something like this:
public static implicit operator UserIdentity(MockUserIdentity src) { return src.UserIdentity; }
or
public static explicit operator UserIdentity(MockUserIdentity src) { return src.UserIdentity; }
The problem is that, as far as I can tell, the โhowโ does not seem to cause an explicit or explicit conversion operation on my layout object. My question is (is it?), I missed something simple here or it wonโt work, because (as I assume) the โhowโ operation looks directly at the class inheritance (which my object does not ...)?
In addition, maybe a little from the topic, but why in the same class cannot be both explicit and implicit operators of the same resulting type? If I miss something stupid, the compiler stops working if I try to use both conversion operators at the same time. I have to choose one or the other.
UPDATE
OK, now I'm completely confused. Maybe I'm getting sloppy, but I tried to do direct casting, and I can't get it to work. I read the statement on MSDN, and this example shows the statement going in the resulting class, not the source class, but I'm not sure if it matters or not (I tried both places in the code below). In any case, I tried to create a simple test bed in order to understand what I can do wrong, but I can not make it work ... That's what I have
class Program { // Shared Interface public interface IIdentity { } // "real" class (not conducive to inheritence) public class CoreIdentity : IIdentity { internal CoreIdentity() { } // Just in case (if this has to be here, that seems unfortunate) public static explicit operator CoreIdentity(ExtendedIdentity src) { return src.Identity; } } // "mock" class (Wraps core object) public class ExtendedIdentity : IIdentity { public CoreIdentity Identity { get; set; } public ExtendedIdentity() { Identity = new CoreIdentity(); } // This is where the operator seems like it should belong... public static explicit operator CoreIdentity(ExtendedIdentity src) { return src.Identity; } } // Dummy class to obtain "current core identity" public class Foo { public IIdentity Identity { get; set; } public CoreIdentity GetCoreIdentity() { return (CoreIdentity)Identity; } } static void Main(string[] args) { ExtendedIdentity identity = new ExtendedIdentity(); Foo foo = new Foo(); foo.Identity = identity; CoreIdentity core = foo.GetCoreIdentity(); } }
But this throws the following exception when I call foo.GetCoreIdentity ():
Cannot pass an object of type "ExtendedIdentity" to enter "CoreIdentity".
and I can't catch any of my explicit operators with a breakpoint, so it looks like he is making this definition without even โtryingโ the conversion routes that I provided.
Of course, I miss something obvious. Does the fact that I have my Identity (in Foo), defined as IIdentity, somehow prevent the resolution of the cast using explicit operators like implementation? It would seem strange to me.
UPDATE (# 2)
It seems to me that I am sending out my post with all these updates (maybe I need to reduce my actions before they are happy with the trigger :)) Anyway, I changed my Foo GetCoreIdentityMethod to do this instead:
public CoreIdentity GetCoreIdentity() { ExtendedIdentity exId = Identity as ExtendedIdentity; if (exId != null) return (CoreIdentity)exId; return (CoreIdentity)Identity; }
and (after clearing the ambiguous reference caused by the presence of an operator in both classes), he took a step in my explicit code for the conversion operator, and it worked as expected. So, I think it seems that explicit operators are not resolved polymorphically (is this the correct understanding?), And the fact that my property was entered as an identifier and not ExtendedIdentity did not allow it to refer to cast logic, even if it was an ExtendedIdentity Type at the time of his call. It strikes me as very peculiar and unexpected ... and kind of miserable.
I do not want to rewrite the keeper of the CurrentIdentity object so that it knows about my special test cast mocks. I wanted to encapsulate this โspecialโ logic in the layout itself, so it really throws me into a loop.