This project is read-only.

SilverUnit support for Reactive Extensions

Jun 18, 2010 at 11:02 AM

Hi,

I've been trying to debug an NUnit test testing Silverlight code using the Reactive Extensions for Silverlight, thinking that this should be fine as long as the Silverlight code didn't use any UI elements. However, it looks like Reactive Extensions also has dependencies on the Silverlight runtime (agcore). For example, I get a TypeInitializationException when Rx is trying to load its System.Concurrency.Scheduler class.

This project together with Typemock looked like a possible solution to my problem, but it did not make any difference in this case. I assume SilverUnit needs to handle each type with a dependency on the Silverlight runtime explicitly. Are there any plans for supporting Reactive Extensions in SilverUnit?

Cheers

Jun 18, 2010 at 11:23 AM
Edited Jun 18, 2010 at 11:27 AM

+1 for me.


I thought I would be able to download this stuff and be able to test Silverlight projects using Rx. I would love to see how I can test this simple code here

public class MyController
{
    private readonly IServiceThing _serviceThing;
    public MyController(IServiceThing serviceThing)
    {
        _serviceThing = serviceThing;
    }

    public long DoRxStuff()
    {
        return _serviceThing.GetNumbers().Last();   //Observable.Lats(this IObservable<T>) will invoke the static ctor of the Sys
    }
}

public interface IServiceThing
{
    IObservable<long> GetNumbers();
}

How can I get the intention of this test to actually work? ie Is Rx or Mocking static properties supported with this product??

[TestMethod]
[SilverlightUnitTest]
public void MyTest()
{
    var sut = new MyController(new FakeServiceThing());
    var actual = sut.DoRxStuff();
    Assert.AreEqual(4, actual);
}
public class FakeServiceThing : IServiceThing
{
    public IObservable<long> GetNumbers()
    {
        return Observable.Interval(TimeSpan.FromMilliseconds(50)).Take(5);
    }
}


If it helps, this is the error from the test (which is expected).
******************************************
*Loading Silverlight Isolation Aspects...*
******************************************

 TEST RESULTS:
---------------------------------------------
TestCase 'TestProject.MyTests.SLRxTestything'
failed: System.TypeInitializationException: The type initializer for 'System.Concurrency.Scheduler' threw an exception.
 System.TypeInitializationException: The type initializer for 'System.Concurrency.Scheduler' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
 at System.Concurrency.Scheduler..cctor()
    --- End of inner exception stack trace ---
 at System.Concurrency.Scheduler.get_ThreadPool()
 at System.Linq.Observable.Interval(TimeSpan period)
 MyTests.cs(97,0): at TestProject.FakeServiceThing.GetNumbers()
 MyController.cs(17,0): at SilverlightApplication.MyController.DoRxStuff()
 MyTests.cs(39,0): at TestProject.MyTests.SLRxTestything()
 at CThru.Silverlight.SilverlightUnitTestAttribute.Execute()
 at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5)
 at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected)
 MyTests.cs(17,0): at TestProject.MyTests.SLRxTestything()


So far I have not been able to find a way to use TypeMockIsolator and CThru to be able to mock out the static property
  System.Concurrency.Scheduler.ThreadPool
or figure out how to replace the method body of it's Schedule method so that I can invoke the passed action immediately.

I would have thought something like this may have worked, however it seems I need to reference both system.core from SL and from Desktop CLR.

[TestMethod]
[SilverlightUnitTest]  // <----- where the magic happens
public void SLRxTestything()
{
    Isolate.Fake.StaticMethods(typeof(System.Concurrency.Scheduler));
    //possibly need to fake out ThreadPool first, but that didn;t work either.
    Isolate.WhenCalled(() => System.Concurrency.Scheduler.ThreadPool.Schedule(null)).DoInstead(ctx =>
        {
            var action = (Action)ctx.Parameters[0];
            action();   //Invoke now.
            return Disposable.Empty;
        });

    var sut = new MyController(new FakeServiceThing());
    var actual = sut.DoRxStuff();
    Assert.AreEqual(4, actual);
}


TIA

Lee Campbell - Hopefully the post formats correctly....4th time...this time with IE6

Coordinator
Jun 18, 2010 at 7:14 PM
can you post an example of a simple test using rx that recreates the problem?
I need to repro this and have not yet tried rx

On Fri, Jun 18, 2010 at 12:02 PM, Freed <notifications@codeplex.com> wrote:

From: Freed

Hi,

I've been trying to debug an NUnit test testing Silverlight code using the Reactive Extensions for Silverlight, thinking that this should be fine as long as the Silverlight code didn't use any UI elements. However, it looks like Reactive Extensions also has dependencies on the Silverlight runtime (agcore). For example, I get a TypeInitializationException when Rx is trying to load its System.Concurrency.Scheduler class.

This project together with Typemock looked like a possible solution to my problem, but it did not make any difference in this case. I assume SilverUnit needs to handle each type with a dependency on the Silverlight runtime explicitly. Are there any plans for supporting Reactive Extensions in SilverUnit?

Cheers

Read the full discussion online.

To add a post to this discussion, reply to this email (CThru@discussions.codeplex.com)

To start a new discussion for this project, email CThru@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
Thanks,

Roy Osherove
www.TypeMock.com - Unit Testing, Plain Smart

Author of "The Art Of Unit Testing" (http://ArtOfUnitTesting.com )
A blog for team leaders: http://5Whys.com
my .NET blog: http://www.ISerializable.com
Twitter: http://twitter.com/RoyOsherove
+972-524-655388 (GMT+2)
Coordinator
Jun 18, 2010 at 7:18 PM
when CThru is running, using the standard Isolator API is not possible (for now).
I'll investigate and try to get a fix for this. it's just a matter of figuring out what aspects to add to the CThru engine to shut off the Schedule static method. should be quote simple, assuming that is the only problematic dependency.

On Fri, Jun 18, 2010 at 12:23 PM, LeeCampbell <notifications@codeplex.com> wrote:

From: LeeCampbell

+1 for me. I thought I would be able to download this stuff and be able to test Silverlight projects using Rx. I would love to see how I can test this simple code here public class MyController { private readonly IServiceThing _serviceThing; public MyController(IServiceThing serviceThing) { _serviceThing = serviceThing; } public long DoRxStuff() { return _serviceThing.GetNumbers().Last(); //Observable.Lats(this IObservable<T>) will invoke the static ctor of the Sys } } public interface IServiceThing { IObservable<long> GetNumbers(); } How can I get the intention of this test to actually work? ie Is Rx or Mocking static properties supported with this product?? [TestMethod] [SilverlightUnitTest] public void MyTest() { var sut = new MyController(new FakeServiceThing()); var actual = sut.DoRxStuff(); Assert.AreEqual(4, actual); } public class FakeServiceThing : IServiceThing { public IObservable<long> GetNumbers() { return Observable.Interval(TimeSpan.FromMilliseconds(50)).Take(5); } } If it helps, this is the error from the test (which is expected). ****************************************** *Loading Silverlight Isolation Aspects...* ****************************************** TEST RESULTS: --------------------------------------------- TestCase 'TestProject.MyTests.SLRxTestything' failed: System.TypeInitializationException: The type initializer for 'System.Concurrency.Scheduler' threw an exception. System.TypeInitializationException: The type initializer for 'System.Concurrency.Scheduler' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object. at System.Concurrency.Scheduler..cctor() --- End of inner exception stack trace --- at System.Concurrency.Scheduler.get_ThreadPool() at System.Linq.Observable.Interval(TimeSpan period) MyTests.cs(97,0): at TestProject.FakeServiceThing.GetNumbers() MyController.cs(17,0): at SilverlightApplication.MyController.DoRxStuff() MyTests.cs(39,0): at TestProject.MyTests.SLRxTestything() at CThru.Silverlight.SilverlightUnitTestAttribute.Execute() at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5) at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected) MyTests.cs(17,0): at TestProject.MyTests.SLRxTestything() So far I have not been able to find a way to use TypeMockIsolator and CThru to be able to mock out the static property System.Concurrency.Scheduler.ThreadPool or figure out how to replace the method body of it's Schedule method so that I can invoke the passed action immediately. I would have thought something like this may have worked, however it seems I need to reference both system.core from SL and from Desktop CLR. [TestMethod] [SilverlightUnitTest] // <----- where the magic happens public void SLRxTestything() { Isolate.Fake.StaticMethods(typeof(System.Concurrency.Scheduler)); //possibly need to fake out ThreadPool first, but that didn;t work either. Isolate.WhenCalled(() => System.Concurrency.Scheduler.ThreadPool.Schedule(null)).DoInstead(ctx => { var action = (Action)ctx.Parameters[0]; action(); //Invoke now. return Disposable.Empty; }); var sut = new MyController(new FakeServiceThing()); var actual = sut.DoRxStuff(); Assert.AreEqual(4, actual); }

Read the full discussion online.

To add a post to this discussion, reply to this email (CThru@discussions.codeplex.com)

To start a new discussion for this project, email CThru@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
Thanks,

Roy Osherove
www.TypeMock.com - Unit Testing, Plain Smart

Author of "The Art Of Unit Testing" (http://ArtOfUnitTesting.com )
A blog for team leaders: http://5Whys.com
my .NET blog: http://www.ISerializable.com
Twitter: http://twitter.com/RoyOsherove
+972-524-655388 (GMT+2)
Coordinator
Jun 18, 2010 at 8:07 PM
Edited Jun 18, 2010 at 8:09 PM

here's a quick RxAspect for CThru I made that made the test you wrote pass. let me know if this works. see if you can make it better if you run into other problems.

I used reflector to see what those methods were trying to return and just returned a new instance of the scheduler (the static constructor did not run).

you'll need to add this line to your start of the test test (not in the setup method):

 

CThruEngine.AddAspect(new RxAspect());

Now the test looks like this:
        [Test]
[SilverlightUnitTest]
public void MyTest()
{
    CThruEngine.AddAspect(new RxAspect());
    
   var sut = new MyController(new FakeServiceThing());
    var actual = sut.DoRxStuff();
    Assert.AreEqual(4, actual);
}

 

here's the aspect:

 

 public class RxAspect : Aspect
    {
        public override bool ShouldIntercept(InterceptInfo info)
        {
            if (info.TypeName.Contains("System.Concurrency.Scheduler"))
            {
                return true;
            }
            return false;
        }
        public override void StaticConstructorBehavior(DuringCallbackEventArgs e)
        {
            e.MethodBehavior=MethodBehaviors.SkipActualMethod;
        }


        public override void MethodBehavior(DuringCallbackEventArgs e)
        {
            if (e.MethodName == "get_ThreadPool" || e.MethodName== "get_CurrentThread")
            {
                var instance = Isolate.Fake.Instance<ThreadPoolScheduler>();
                e.ReturnValueOrException = instance;
                e.MethodBehavior=MethodBehaviors.ReturnsCustomValue;
            }
            base.MethodBehavior(e);
        }
    }

 

Jun 18, 2010 at 11:23 PM
You rock roy. Will try when I'm sober.

Sent from my BlackBerry® wireless device


From: "royosherove" <notifications@codeplex.com>
Date: 18 Jun 2010 12:07:10 -0700
To: <lee.ryan.campbell@gmail.com>
ReplyTo: CThru@discussions.codeplex.com
Subject: Re: SilverUnit support for Reactive Extensions [CThru:216494]

From: royosherove

here's a quick RxAspect for CThru I made that made the test you wrote pass. let me know if this works. see if you can make it better if you run into other problems.

I used reflector to see what those methods were trying to return and just returned a new instance of the scheduler (the static constructor did not run).

you'll need to add this line to your start of the test test (not in the setup method):

CThruEngine.AddAspect(new RxAspect());

here's the aspect:

 public class RxAspect : Aspect
    {
        public override bool ShouldIntercept(InterceptInfo info)
        {
            if (info.TypeName.Contains("System.Concurrency.Scheduler"))
            {
                return true;
            }
            return false;
        }
        public override void StaticConstructorBehavior(DuringCallbackEventArgs e)
        {
            e.MethodBehavior=MethodBehaviors.SkipActualMethod;
        }


        public override void MethodBehavior(DuringCallbackEventArgs e)
        {
            if (e.MethodName == "get_ThreadPool" || e.MethodName== "get_CurrentThread")
            {
                var instance = Isolate.Fake.Instance<ThreadPoolScheduler>();
                e.ReturnValueOrException = instance;
                e.MethodBehavior=MethodBehaviors.ReturnsCustomValue;
            }
            base.MethodBehavior(e);
        }
    }