Monday, October 17, 2011

Using callbacks with Moq to check state

Here is the scenario, I have a method that takes an object, however - nowhere in your CUT (class under test) can you publicly access this object to verify state the state of it. I run into this scenario a lot regarding view models, the view model exposes things that we need to look at and interact with as public properties but anything the user doesn’t interact with or see is private which can make testing a pain. Let’s look at an example of something we can easily test before we get to the problem.

[TestMethod]

public void SaveCommandGetsSetWhenConstructed()

{

//Arrange

var adapterMock = new Mock<INewOrderAdapter>();

adapterMock.Setup(x => x.DeclinedBuyItNowPartNumbers)

.Returns(new List<string>() { "12345" });

var vm = new PartDeclinedViewModel(eventAggregator, adapterMock.Object)

{

SelectedLineItems = new ObservableCollection<DeclineReasons>()

{

DeclineReasons.CONDITION

},

CommentsText = "Testing",

SelectedPartNumber = "12345"

};

//Act (done when the constructor is initialized)

//Assert

Assert.IsNotNull(vm.SaveCommand);

}

So - you have defined SaveCommand in your view model, it’s a public delegate command, I can easily write a test that verifies that I am setting the method when we call the constructor for our class. Look at the test below – it does just that,(there are a few things in the arrange portion of the test that are telling me my view model needs a little refactoring but ignore that for now).

Now that we have looked at that example, what if the method that the delegate command we are using for the SaveCommand calls something that changes a private property? Whatever it is isn’t visible to the user so we don’t have anything that is publicly accessible in the view model. We don’t need it. Except we want to test that our method does the right thing to this private object. We can use a callback to set a value to a variable that is scoped inside the test method and then call our asserts on the state of the object. Let me try to use some more examples.

When we create the view model in the test above you can see that a mock adapter is created. This mock adapter has methods we need to mock out using Mock.Setup(), this of course means we can make them do whatever we want them too. So instead of having adapter.Save(myType, myObject) do whatever it normally does (we aren’t testing that here). We can mock it to say “Take the variable that was passed in and put it in this local variable” – that is what the callback does. See the test below which does just that.

[TestMethod]

public void LineItemIdGetsSetIfExists()

{

//arrange

DeclinedPart declinedPart = new DeclinedPart();

var lineItem = new LineItem() {PartNumber = "12345", LineItemId = 555};

var currentSaleOrder = new CreateSalesOrder();

currentSaleOrder.LineItems = new List<CreateLineItem>() { (CreateLineItem)lineItem };

var adapterMock = new Mock<INewOrderAdapter>();

adapterMock.Setup(x => x.DeclinedBuyItNowPartNumbers)

.Returns(new List<string>() {"12345"});

adapterMock.Setup(x => x.CurrentSalesOrder).Returns(currentSaleOrder);

adapterMock.Setup(x => x.SaveDeclineReason(It.IsAny<DeclinedPart>())).

Callback((DeclinedPart x) => declinedPart = x);

var vm = new PartDeclinedViewModel(eventAggregator, adapterMock.Object)

{

SelectedLineItems = new ObservableCollection<DeclineReasons>()

{

DeclineReasons.CONDITION

},

CommentsText = "Testing",

SelectedPartNumber = "12345"

};

//Act

vm.SaveCommand.Execute();

//Assert

Assert.AreEqual(declinedPart.LineItemId, lineItem.LineItemId);

}

There you have it, now you look at the local variable (the one you created in your test method) and check that your method does what you wanted it to. People will point out that you can use things like private accessors for this task however I tend to shy away from those. They don't always seem to be reliable and they tend to make the tests more confusing - in my opinion of course. at any rate - this is just another nifty little trick for examining the state of something you don't necessarily have direct access to.

Monday, February 28, 2011

Musings on using a module catalog with Prism

anyone using prism is probably familar with the bootstrapper, the documentation defines the bootstrapper as a class responsible for initialization of an application built using Prism and if you dig into the code for it you will see lots of virtual methods that you can override when setting up your application, one of those is the CreateModuleCatalog(). There are several ways to initialize your modules but using an xaml file is incredibly convenient especially if you only want certain parts of your application to load under certain conditions. Where I work we recently decided to employ this feature so that we could load a subset of the application in the warehouse and not have the sales and other modules loading up at run time, on the flip side the warehouse module doesn't load when the sales team loads the application. The great part for the developer is you don't end up with multiple code bases, your core and infrastructure is shared in one application and different people see different parts of the app depending on what is in the ModuleCatalog.xaml file.

With that said I wanted to point out a little snafu I ran into when configuring the catalog and loading it from the xaml file. most of my modules loaded just fine however one of them was not playing nicely - I was pulling my hair out looking at the module properties and examining it with RedGate but it failed to load each time so I started digging through the prism code. I noticed that inside of ModuleInitializer there was a method called CreatModule and it was calling GetType - here is the line of code

Type moduleType = Type.GetType(typeName);

Then it was checking to see if the moduleType var was null and sure enough it was. That gave me the bright idea... Why not call getType on the module itself and stick that in a variable so I could copy and paste? That is exactly what I did. Actually I think I popped a message box but whatever, once I had the exact info from get type I copied an pasted that in to the ModuleCatalog.xaml file and all my problems where gone! What you are really looking for is the
AssemblyQualifiedName. Here is a screen shot.


The information you get from there goes in the ModulesCatalog.xaml - here is a screen cap.


Just to sum it up here is a quick screen of CreateModuleCatalog

Copying items to a output directory using post-build events

Certain times you are going to need to move things to some sort output directory after they are built, for whatever reason - maybe your program is looking for a list of modules that it will load when it fires up (you can do this with prism)?

It's easy to do, just go to the "Properties" for your project and select "Build Events". in the box titled "Post-Build event command line" enter your xcopy command. Somthing like this.


xcopy "$(TargetDir)PARTSFinderModule.dll" "$(SolutionDir)\MyProject\bin\$(PlatformName)\$(ConfigurationName)\DirectoryModules" /Y


That's it.

Friday, January 14, 2011

Styling the combox box in WPF


If you want to play with the style of the combo box in WPF the easiest thing to do is use expression blend, drag a combo box control onto you project then click, "Edit Template" -> "Edit a copy"... This will take the entire default template for the combox box and put it into your XAML file.



Now go to the XAML and you can grab the entire style and do whatever you like with it... I usually put things like this into a main poject under the solution, something like "shared" is a good name for the project... One thing that is important to note though is that you have to include a reference to the PresentationFramework.Aero assembly cause you will need the Microsoft.Windows.Themes namespace.

Followers