Observable

Various…

http://pastebin.com/4USNa3bc

Advertisements

Silverlight Unit Testing setup

Silverlight Unit Test Framework installation

As any fule doth know (by now), Microsoft are investing next-to-zero effort (aka abandoned) in Silverlight development support. And part of that development is Silverlight unit testing. What does one (investment) have to do with the other (unit testing)? Well, having installed the Nuget SLUT package on my home pc…

PM> Install-Package SilverlightToolkit-Testing

SilverlightUnittest04… I noticed this in the description:

SilverlightUnittest05

Anyway, things you might not know if you have not run Silverlight tests before:

They are an application in their own right – you have to create your Silverlight (test) application, and set it as the startup project

You may therefore need to edit the RootVisual value in  Appl.Xaml.cs :

private void Application_Startup(object sender, StartupEventArgs e) {
RootVisual = UnitTestSystem.CreateTestPage();
}

The CreateTestPage call then evidently goes looking for your unit tests in the application (or maybe it doesn’t – I just don’t have any code other than test code in the project).

I’m using Prism, so my list of references includes Microsoft.Practices.Prism (4.1 for me), and this must be the one that references Silverlight, not Desktop/WPF. This and the other references are highlighted:

SilverlightUnittest08

With those in place, you can then write your tests. Note that for simplicity I instantiate the  Composer class, which is part of the model, rather than any viewmodel proxy. Interesting blogs on proxies are here and here . But in summary, the test that should only be aware of public properties for the view model, is aware of public properties for the model, which is bad. This is a very simple example, as you see. And I’m sure there is a way to generate a version generated from a template, but I can’t find it any longer, so me, I’ll just fill in my own usings etc.

View model test code example:

SilverlightUnittest09

MVVM layout in the project – only the model and viewmodel are of interest right now:

SilverlightUnittest10


//Composer.cs:

namespace SilverlightApplication26.Model {
	public class Composer {
		public string Name { get; set; }
		public string CountryOfBirth { get; set; }
	}
}

// ComposerService.cs:

using System.Collections.Generic;

namespace SilverlightApplication26.Model {
	public class ComposerService {
		private readonly List<Composer> _composers;

		public ComposerService() {
			_composers = new List<Composer>
				{
					new Composer {Name = "SchnuffelHausen", CountryOfBirth = "Austria"},
					new Composer {Name = "Mozart", CountryOfBirth = "Austria"},
					new Composer {Name = "Bach", CountryOfBirth = "Germany"},
					new Composer {Name = "Wagner", CountryOfBirth = "Germany"},
					new Composer {Name = "Ravel", CountryOfBirth = "France"},
				};
		}

		public List<Composer> GetComposers() {
			return _composers;
		}

		public void AddComposer(Composer composer) {
			_composers.Add(composer);
		}
	}
}

// ComposerViewModel.cs:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using Microsoft.Practices.Prism;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;
using SilverlightApplication26.Model;

namespace SilverlightApplication26.ViewModel {
	public class ComposerViewModel : NotificationObject {
		private ObservableCollection<Composer> _composers;
		private readonly ComposerService _composerService = new ComposerService();

		public ComposerViewModel() {
			SubmitCommand = new DelegateCommand<object>( OnSubmit);
			_composers = GetComposers();
		}

		public ObservableCollection<Composer> GetComposers() {
			if (_composers == null || _composers.Count == 0) {
				_composers = new ObservableCollection<Composer>(new List<Composer>());
				_composers.AddRange(_composerService.GetComposers());
			}
			return _composers;
		}

		public void AddComposer(Composer composer) {
			_composers.Add(composer);
		}

		public ICommand SubmitCommand { get; private set; }
		private static void OnSubmit(object obj) {
			MessageBox.Show("stuff");
		}
	}
}

// ComposerViewModelUnitTests.cs:

using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SilverlightApplication26.Model;
using SilverlightApplication26.ViewModel;

namespace SilverlightUnitTest {
	[TestClass]
	public class ComposerViewModelUnitTests : SilverlightTest {
		[TestInitialize]
		public void Initialize() {
		}

		[TestMethod]
		public void ComposerCountIsCorrect() {
			var composerViewModel = new ComposerViewModel();
			var composers = composerViewModel.GetComposers();
			Assert.AreEqual(5, composers.Count);
		}

		[TestMethod]
		public void AddingOneComposerIncreasesCountByOne() {
			var composerViewModel = new ComposerViewModel();
			var composers = composerViewModel.GetComposers();
			Assert.AreEqual(5, composers.Count);
			composerViewModel.AddComposer(new Composer { CountryOfBirth = "Norway", Name = "Jones" });
			Assert.AreEqual(6, composers.Count);

		}
	}
}

Oh yes, this is the end goal:

SilverlightUnittest11

I recognise the tests have little or no value, because really the constructor should be injected with some IComposer: right now, all that is being tested is the domain model / concrete repository.

Hm, just found this, which is really good on MVVM.

 

Diary of a reluctant gardener

So no direct evidence of me doing stuff, so you’ll just have to take my word for for it:

GardeningWork01

The work is replacing… anyway, it’s hard, it’s not my favourite thing, but once it’s all over, it will look nice.

I am aware that I have done zero music for some time now. But I haven’t been idle. I have my plan.

Anyway… Prism: Prism libraries implement the INotifyPropertyChanged etc and ICommand interfaces. For now, this is my cheatsheet for ICommand (right now, just an example of a by-hand implementation):

Office Lens_20140801_231330_processed (1)

 

ICommand

ICommand – there is a very good if somewhat old (so what?) step through of the principles and possible implementations on MSDN.

ICommand01

Trying it out on a Visual Studio App template:

ICommand02

This btw could be useful for MVVM stuff:

ICommand03

Back to the app – I really want to set up my own INPC/Observable Collection/ICommand implementation/template that I can apply to a new project and have something running within say 30 minutes. Back to the app, I said…

The generated solution gives you not a lot:

ICommand04

Except that StandardStyles.xaml is massive and worthy of some investigation. Create a folder and the helper class to implement ICommand (should be in its own folder or project, but anyway):

ICommand05

The stubbed implementation of ICommand, waiting for stuff:

 

ICommand06

Trying a naive implementation of the Execute method…

ICommand07

, I forgot that it is an interface – it expects an object as a parameter to Execute:

 

ICommand08

Time for bed. More tomorrow maybe – it sometimes amazes me that I do a 12 hour day at the office, and I come home, and I want to do more. Actually it’s different. Someone do the dishes for me? Thought not. BTW those people who are following me… Thanks! 🙂 I’m trying to get more of a mix of stuff, i.e. stuff not related to IT, onto the pages.. but not trying hard enough. You guys will be shocked in a good way when you say what I’ve been doing to Bamboo! No, not Wacom, I mean bamboo:

IBamboo09

It looks alien, like Alien. But it has no answer to this…

IBamboo10

(Cue Evil laugh.)

So accepting that this doesn’t even work:

public class SimpleCommand : ICommand {
		public bool CanExecute(object parameter) {
			throw new NotImplementedException();
		}

		public void Execute<T>(Action<T> parameter) {
			throw new NotImplementedException();
		}

		public event EventHandler CanExecuteChanged;
	}

… let’s bring it back to something that at least does work. I’m creating a Console application now, set that as the startup project, reference the SimpleCommand class, and run it:

Hm, no you don’t apparently:

ICommand09

Hm, can’t immediately see why a  console app cannot use a reference to a Windows App. Let’s dispense with that approach then, and plug it all into a console app.

ICommand10

Just 2 bits then. The implementation of ICommand:

ICommand11

expanded…

ICommand12

, and the program to run:

ICommand13

namespace ConsoleApplication1 {
	using System;
	using System.Windows.Input;

	public class SimpleCommand : ICommand {
		public bool CanExecute(object parameter) {
			if (parameter != null) {
				Console.WriteLine("[CanExecute:] Yes, you can execute)");
				return true;
			}
			Console.WriteLine("[CanExecute:] No, you will not execute");
			return false;
		}

		public void Execute(object action) {
			Console.WriteLine("[Execute:] [action] was [{0}]. Can I execute?", action != null ? "Not null" : "null");

			if (CanExecute(action)) {
				Console.WriteLine("[Execute:] Oh good. Apparently, I can Execute.");
				return;
			}
			Console.WriteLine("[Execute:] Bother. Apparently, I cannot Execute.");
		}

		public event EventHandler CanExecuteChanged;
	}
}

using System;

namespace ConsoleApplication1 {
	public class Program {
		private static void Main(string[] args) {
			ClickIt();
		}

		private static void ClickIt() {
			var o = new object();
			var simpleCommand = new SimpleCommand();

			simpleCommand.Execute(o);
			Console.WriteLine("--------------------------");
			simpleCommand.Execute(null);

			Console.ReadLine();
		}
	}
}

Time for a part 2, I think…