This project is read-only.

How are Silverlight calls selected for redirection?

Feb 26, 2009 at 8:19 PM
Perhaps this is due to my lack of Silverlight knowledge, but I don't seem to have an understanding of how Silverunit filters just Silverlight calls. I have inspected the source code, and while I see several occurences of RedirectCalls, I still miss the whole picture. For example, one place where RedirectCalls is executed is within TriggerPropertyCallback. TriggerPropertyCallback itself is called from a few places, for example, from ItemCollectionRedirects SetValue. Eventually I come to ItemsControlAspect.ConstructorBehavior where there is a check if itemsType is a subclass of ItemsControl. Here I get lost. ItemsControl is from System.Windows.Controls. Is this how Silverlight is detected? E.g. anything that is subclassed from ItemsControl should be redirected?
Coordinator
Feb 26, 2009 at 9:44 PM
Under the "Aspects" folder, every class that inherits from "Aspect" is essentially a "rule". Rules are applies for every method call, as long as it fits the logic inside the various XXBehavior overriden methods.
For example, in your case, you are right. *every* class that inherits from ItemsControl gets a specific faked behavior. For example in DependecyObjectAspect, every DependencyObject based class in the system is *redirected* at creation time to a matching DependencyObjectRedirects class found in the project.
Feb 27, 2009 at 7:09 AM
I see. Can this technique be fragile? For example, if we take this code:

If e.TypeName.Contains("Control") AndAlso e.MethodName = "get_IsEnabled" Then...

Does this means that anything that has "Control" in its name and has IsEnabled property will be chosen? In a large project chances for similar classes/methods are high. But I guess this can easily be resolved by checking namespace.

Another thing: when I look at the tests in VB, they all use SilverUnitTest attribute, and that's it. I am trying to figure out how to do more advanced stuff, like setting values, throwing exception etc. Such examples would be very useful to clarify how to create aspects.

 


 

Coordinator
Feb 27, 2009 at 9:08 AM
yes ou can just check that the typename (which contains the fullnamespace) begins with a specific namespace.
as for the tests, the whole point is that the isolation is transparent. the tests can then use Isolator to do the regular ad-hoc behavior modifications
Using.TheseCalles.WillThrow(new Exception)
    dim s = txt.Text
end Using

inside the test.
these can live side by side with the isolation aspects
Feb 27, 2009 at 9:16 AM
What if there are several aspects to be mixed in one test? E.g. will such combination work: [Test, Isolated, SilverunitTest, SqlTest, OracleTest]?
Coordinator
Feb 27, 2009 at 9:25 AM
You don't add aspects by attribute. you add them by adding more aspect classes to the current assembly. just make sure the aspect don't change the behavior of the same method call in different ways (by definistion they should be looking at different things..)
in that case you'll get a special exception that say what conflict you got.

we can enable multiple attribute support by changing the code inside the SilverlightUnitTest attribute to check if CThru as already been initialized (take a look at the code for it). right now only one attribute would work cleanly.

Feb 27, 2009 at 10:44 PM
I played a little with CThru and made a little toy: disabled calls to MSMQ.

 

public class MsmqAspect : Aspect
{
    public override void MethodBehavior(DuringCallbackEventArgs e)
    {
        if (e.TypeName.Equals("System.Messaging.MessageQueue"))
        {
            e.MethodBehavior =
MethodBehaviors.SkipActualMethod;
        }
    }
}

Then I defined MsmqUnitTestAttribute and all tests that I marked with such attribute no longer talked to MSMQ. Great, however there a some things I would like to figure out.

1. There does not seem to be a place for FluentAOP. You mentioned that using FluentAOP would simplify development of SilverUnit, but to me using CThru engine looks straightforward. Of course I've been only making some toys. It would be great if you come with some examples of where FluentAOP is preferrable.

2. I am thinking about packaging aspects. My original idea of creating multiple attributes is not very elegant: all those attributes will only differ in attribute name. The actual code (overridden Execute) is exactly the same. This is what I dislike. I would prefer making only one attribute class (e.g. AspectUnitTest) with AllowMultiple=true and property "AssemblyName" that could be specified multiple times. So the idea is to list multiple aspects that could come from different assemblies: the method under test may touch multiple environments that would need to be isolated. Unfortunately this does not seem to be possible: AssAspectsInAssembly can't deal with a list of assembly names, it needs actual assembly instance.
Of course you can say that if multiple environments need to be isolated from a single test, then it's a bad unit test. Yes it is, but even if we deal with "good" unit tests that only need to isolate single environment like Silverlight, current approach requires to either combine all aspects in once assembly or add support for multiple attributes and implement as many custom attributes as there are different subsystems to be isolated. Perhaps that's the only way to go, but then I would at least put implementation of the attibute base in CThru and keep in different custom attribute overrides only evaluation of executing assembly, e.g.:

CThru implementation:

public
override object Execute()
{
    if (!m_WasInit)
    {
        m_WasInit =
true;
        CThruEngine.AddAspectsInAssembly(GetAspectAssembly());
    }
    CThruEngine.StartListening();
    base.CallDecoratedMethod();
    CThruEngine.StopListening();
    return null;
}

public abstract Assembly GetAspectAssembly()

In the actual aspect assembly:

public override Assembly GetAspectAssembly() { return Assembly.GetExecutingAssembly(); }

This will result in multiple attribute definitions but at lease most of the code will be reused.

 

Coordinator
Mar 1, 2009 at 3:43 PM
1. Currently FluentAOP is an thought excersize. An example of stuff you can do on top of CThru. to get the brain juices flowing.
2. re packaging aspects: There is no good story for packaging right now, but there could easily be one. It does not have to be attribute based either.
It could just be code that initializes CThruEngine at the beginning of an app run once.
Mar 2, 2009 at 7:16 AM
OK. I will continue playing with CThru. At the moment I feel I am not ready to join CThru as contributor. I need to build a better understanding of the concept.