chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Hi again,

I'm trying to test Silverlight custom control using SilverUnit.

I have XAML file with 2 controls on it, text box and command button.

Here's the code:

public partial class MyControl : UserControl
{
public IList<string> Numbers { get; set; }

public MyControl()
{
InitializeComponent();

Numbers = new List<string>();
}

private void txtNumber_TextChanged(object sender, TextChangedEventArgs e)
{
int number = 0;
string text = this.txtNumber.Text;
if (!int.TryParse(text, out number) || string.IsNullOrEmpty(text))
this.cmdAdd.IsEnabled = false;
else
this.cmdAdd.IsEnabled = true;
}

private void cmdAdd_Click(object sender, RoutedEventArgs e)
{
string text = this.txtNumber.Text;
Numbers.Add(text);
}
}

And I'd like to test UI that is text box's Text_Changed event and command button's Click event. I've created regular MS test project (not MS Silverlight test project) and have this code:

[TestClass]
public class UnitTest1 : SilverlightTest
{
private MyControl myControl;

...

[TestInitialize()]
public void MyTestInitialize()
{
myControl = new MyControl();
this.TestPanel.Children.Add(myControl);
}

[TestMethod, SilverlightUnitTest]
public void TestWithSilverUnit()
{
Assert.IsTrue(true);
}

...

}

It compiles successfully, but when I run the test it gives me an error:

Initialization method TestProject2.UnitTest1.MyTestInitialize threw exception. System.TypeInitializationException: System.TypeInitializationException: The type initializer for 'System.Windows.DependencyObject' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MS.Internal.JoltHelper' threw an exception. ---> System.TypeLoadException: Method 'Create' in type 'System.Net.BrowserHttpWebRequestCreate' from assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' does not have an implementation..

Stack trace is here:

MS.Internal.JoltHelper..cctor()
MS.Internal.JoltHelper.get_ThreadID()
MS.Internal.XcpImports.CheckThread()
System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex)
System.Windows.DependencyObject..ctor()
System.Windows.DependencyObject.ManagedReferencesToken..ctor()
System.Windows.DependencyObject..cctor()
System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex)
System.Windows.UIElement..ctor(UInt32 nKnownTypeIndex)
System.Windows.FrameworkElement..ctor(UInt32 nKnownTypeIndex)
System.Windows.Controls.Control..ctor(UInt32 nKnownTypeIndex)
System.Windows.Controls.UserControl..ctor()
SilverlightApplication1.MyControl..ctor() in D:\Corgent Diagram\Test projects\Silverlight\SilverlightApplication1\SilverlightApplication1\MyControl.xaml.cs: line 19
TestProject2.UnitTest1.MyTestInitialize() in D:\Corgent Diagram\Test projects\Silverlight\SilverlightApplication1\TestProject2\UnitTest1.cs: line 68

It fails at this line in MyTestInitialize method:

myControl = new MyControl();

I suppose I didn't do something in proper way, but I'm not sure what.

Could you help me with this, please?


Thank you in advance.

Goran
asked by tesicg (1.3k points)

13 Answers

0 votes
Hi Goran,

For some reason SilverUnit is not running when you run the test. A possible cause for this may be running with Isolator disabled. How are you running the test? if you are running from Visual Studio, make sure that Isolator is enabled in the Tools menu. If you are using an external test runner, you should run that with TMockRunner (see https://www.typemock.com/Docs/UserGuide/ ... nning.html).

Please let me know if this helps.

Thanks,
Doron
Typemock Support
answered by doron (16.5k points)
0 votes
Hi Doron,

I'm trying to run the test from within VS2008. Typemock Isolator is enabled.

It's crucial for us to have the ability to test UI.


Regards,

Goran
answered by tesicg (1.3k points)
0 votes
Hi Goran

It looks that version of SilverUnit you are using does not match the version of the Isolator installation.
Try to download the latest version of SilverUnit and install version 5.3.0 of the Isolator.
This should make it work.
answered by ohad (35.5k points)
0 votes
I have the latest version of Isolator and SilverUnit and it still doesn't work.

Can I use regular Isolator inside of MS Silverlight unit test framework? I mean inside of class that inherits from SilverlightTest:

[TestClass]
public class Test : SilverlightTest
{
...
}

When I try to add TypeMock.dll to "References" section, there's an information message that says: "You can't add a reference to TypeMock.dll as it was not built against the Silverlight runtime. Silverlight projects will only work with Silverlight assemblies." Also, I'm not able to add CThru.dll and CThru.Silverlight.dll. I've got the same message. I use VS2008.

I prepared the presenation project for using TypeMock Isolator without Silverlight, but I need it for Silverlight as well. I really don't know how to mix Silverlight and TypeMock Isolator. The management in my company can make decision to buy TypeMock Isolator based on my presentation.

I really need your help.


Thanks in advance.

Goran
answered by tesicg (1.3k points)
0 votes
Goran,

What version of SilverLight are you working against? SilverUnit was not tested yet against the new SL3 beta. Also, can you send me your test project with basic classes under test?

Thanks,
Doron
Typemock Support
answered by doron (16.5k points)
0 votes
Hi Doron,

We use Silverlight 2.0.

I like to mix Microsoft Silverlight Unit Test Framework, which runs tests in browser, not in Visual Studio, and TypeMock Isolator, but I can't add basic DLLs. Microsoft Silverlight Unit Test Framework has enough abilities for API and UI testing, but I'd like to use mock objects inside of that framework.

You can test it easily if you install Microsoft Silverlight Unit Test Framework, create new Silverlight Test Project and try to use TypeMock Isolator by adding references to TypeMock.dll and Typemock.ArrangeActAssert.dll to "References" section of Silverlight Test Project.

I need to use Microsoft Silverlight Unit Test Framework because it gives me all abilities to test Silverlight code and I only need some mock framework to use it inside it. I think it's natural approach.


Goran
answered by tesicg (1.3k points)
0 votes
I've setup a wiki page with things that might help:
http://cthru.codeplex.com/Wiki/View.asp ... %20running

Please let me know if this helps fix the problem.

And no, you *cannot* use SilverUnit inside the Silverlight test framework since SilverUnit is not a silverlight based project. it is meant to be used as a regular non silverlight test project that has a reference to the silverlight based project.

If you'd just like to use regular mock objects there is a silverlight compatible version of Rhino Mocks and Moq out there that can help with that. but they will not isolate you from the silverlight runtime problems. they will just support the regular test cases.

Until there is a silverlight based Typemock Isolator version, this is what can be done.

Roy
answered by royo (2k points)
0 votes
I've just rechecked your test code. I think the problem you see in your test is because you are creating the instance of MyControl in your TestInitialize method. I'm pretty sure that the SilverUnit engine has not started yet when this call is made.
If you were to create the instance of MyControl in the actual test and not in the TestInitialize then the SilverUnit engine will have started to work and would isolate you from the problem

Please tell me if this helps.
answered by royo (2k points)
0 votes
Hi Roy,

First of all thank you very much for your support. I also have your book "The art of unit testing", which is excellent.

I've made my basic test sample to work without using Microsoft Silverlight Unit Test Framework, which means I used regular, non-Silverlight test project. What do I have in my project? I have MyControl Silverlight page:

public partial class MyControl : UserControl
{
...
}

with one TextBox control and one Button control on it. The name of TextBox control is txtNumber and the name of Button control is cmdAdd. I have event handlers for both controls, txtNumber_TextChanged for txtNumber control and cmdAdd_Click for cmdAdd control. Also, I set initally cmdAdd control's IsEnabled property to "False". In code-behind, I'm checking in txtNumber_TextChanged event if the text entered is number and if it is cmdAdd button will be enabled. If the text is not a number, cmdAdd control will be disabled. When I click cmdAdd button, the text (number) will be added to the list. The code is here:

public partial class MyControl : UserControl
{
public IList<string> Numbers { get; set; }

public MyControl()
{
InitializeComponent();

Numbers = new List<string>();
}

private void txtNumber_TextChanged(object sender, TextChangedEventArgs e)
{
int number = 0;
string text = this.txtNumber.Text;
if (!int.TryParse(text, out number) || string.IsNullOrEmpty(text))
this.cmdAdd.IsEnabled = false;
else
this.cmdAdd.IsEnabled = true;
}

private void cmdAdd_Click(object sender, RoutedEventArgs e)
{
string text = this.txtNumber.Text;
Numbers.Add(text);
}
}

In my regular MS Test project I have this:

[TestClass]
public class UnitTest1
{
private MyControl myControl;

[TestMethod, SilverlightUnitTest]
public void TestMethod1()
{
myControl = new MyControl();

myControl.txtNumber.Text = "1";

Assert.IsTrue(myControl.cmdAdd.IsEnabled);
}

As you can see I'd like to test if cmdAdd control is enabled or disabled depends on the content of txtNumber control. In this test case, I set proper value (number) and the test should pass. If I set improper value (text), the test shouldn't pass. When I run the test, it fails on this line:

myControl.txtNumber.Text = "1";

with this error message:

"Test method TestProject1.UnitTest1.TestMethod1 threw exception: System.NullReferenceException: Object reference not set to an instance of an object.."

txtNumber is null.

I'm able to test this sucessfully under Microsoft Silverlight Unit Test Framework using this code:

[TestClass]
public class Test : SilverlightTest
{
private MyControl myControl;

[TestInitialize]
public void TestSetup()
{
myControl = new MyControl();
this.TestPanel.Children.Add(myControl);
}

[TestMethod]
[Asynchronous]
public void TestWeCanAddValidNumber()
{
TextBoxAutomationPeer textBoxPeer = new TextBoxAutomationPeer(myControl.txtNumber);
IValueProvider valueProvider = (IValueProvider)textBoxPeer;
ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(myControl.cmdAdd);
IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;

EnqueueCallback(() => valueProvider.SetValue("1"));
EnqueueConditional(() => buttonPeer.IsEnabled());
EnqueueCallback(() => buttonInvoker.Invoke());

EnqueueTestComplete();
}

So, my question is how to test events in some UI using SilverUnit? How to make my test above to work without using Microsoft Silverlight Unit Test Framework?


Thank you in advance.

Goran
answered by tesicg (1.3k points)
0 votes
SilverUnit does not load any XAML and so any inner controls that are loaded by XAML are no loaded doing a pure unit test.
That means that you'll need to *set* the txt box in your control to a new TextBox in your test before you can start using it.

Remember - pure unit testing will not load XAML files and such things that only happen when running inside the silverlight runtime. You can just test logical code in a class under test.

By default, all controls under SilverUnit will always be Enabled.
You can only test logic that is set by custom code, not by XAML states.
answered by royo (2k points)
...