niedziela, 11 września 2016

Unit Testing and NullArgumentException Assertions

One of the coolest things about TDD is that you don't have to write any code before you know the reason, and some reasons can be quite trivial... Like the NullArgumentException checks on constructor. I really like the idea of Fail-fast design so I can watch debugger less often so I always do those assertions. How does it look for average middle layer class?

Part of RpcClientTest.cs

And this is alright, you can clearly see what those tests are for and they serve a good purpose. But wait. Can we do it shorter? Can it take less time? When I modify parameters on ctor I'll have to change all of them.

Now don't be sad. Wanna do it that way?

Part of RpcClientTest.cs after change

Hold on. How does it work?

Well quite simply. Method ThrowsOnAnyNullArgument takes class Type as generic parameter and array of valid, ordered params that will let constructor be invoked correctly. Behind the scenes appropriate constructor of given Type is selected, based on number and Type of parameters. After that it is being invoked for each given parameter to check if replacing current one with null will throw NullArgumentException.

That replaces three tests with just one still doing its job properly. Here's first version of it's code with covering tests.

ConstructorAssertTest.cs

ConstructorAssert.cs

czwartek, 16 czerwca 2016

Switching on Type

One of the first things I've learned long time before my journey with C# was a conditional statement. "If-else" really makes life simple. When I faced more complex scenarios, swich kicked it, great thing for simple factories or in my case ViewTemplateSelector. A class that contains all the views and provides DataTemplate to display current view model in.

The problem was that view is selected by view models type and switch built in C# doesn't support switching on types. What to do, what to do...Lets do a type switch!

Looking on original switch statement gives pretty clear idea how it should work.

  • First of all there's an object to switch on, however I'll have it last, supplying with Execute method after everything is set.
  • Set? Right there are the cases. So what to do when Type is matched.
  • What if is not? Oh, the default case.
  • Do I need to fall through the cases? I can't see a reason to do it here.

And thats what I came up with. default case is called fallback because it felt more like fallback value used when binding in XAML than actually default action, it's kind of last stand where you usually don't want to go in scenario I described. So I made it optional. If that ViewTemplateSelector won't be able to find view for my view model than I consider it as a mistake and don't want to let it go unnoticed. So by default, when there's no match exception will be thrown. If exception is not what you want, constructor allows you to set case for fallback.
Each case is set in dictionary and simply retrieved by key when executing switch, then it returns result of invoked Func. When case is not present, fallback is attempted and if that doesn't exist, we have exception. And thats it. All the code below.

TypeSwitch.cs

TypeSwitchTest.cs

ViewSelector.cs

piątek, 4 marca 2016

MVVM - Improving RelayCommand

One of the simpliest and ingenious things separating views from view models is ICommand. Three simple methods this interface provide enough functionality to satisfy most of user input scenarios, on top of that we receive full control during unit testing. RelayCommand is simple implementation of that interface. Usually taking Action to execute and Predicate for CanExecute check. Those two probably won't change because there's nothing specific about them. What already changed is the way that CanExecuteChanged is raised.

With WPF applications we have CommandManager.RequerySuggested event inside System.Windows.Input namespace. That one is being raised when user interacts with UI.

If you set the breakpoint within your condition and debug it, you'll see that it's being hit almost instantly after you get focus on UI. Brutal but easy to use.

Now when I was trying to do the same in Windows Phone 8.1 app, surprise came at once. CommandManager doesn't exist anymore. Vanished. Oh no, what now. I did some quick search on the net and the most obvious solution appeared. Right now you can simply expose invocator from your command and call it from your ViewModel. Wow!

Yea, what a mess. Alright, I don't want it. So I hooked up on what I already have. My ViewModel already have INotifyPropertyChanged implemented on it. Why not. I derieved from RelayCommand and created WatchingRelayCommand. As the name says - it's watching. Watching the properties that can affect its execution. All I need to do is to pass context and the property names. It's attaching itself to INotifyPropertyChanged on context and each time when some property changes on the ViewModel, command checks if it's interested in that property and if so raises CanExecuteChanged.

On top of that small test ViewModel and couple of tests. When the RelayCommandTestViewModel is instantiated condition is not satisfied (Id as integer by default sets to 0). Constructor creates command with condition that will check if value passed in constructor is matched with changed Id. You can see that if condition is still not satisfied event won't trigger. Thats actually because my implementation of RelayCommand that checks previous state of condition.