Wednesday, December 14, 2016

Testable WinForms Applications

Introduction


Today, WinForms apps mainly belong to legacy code because of increasing popularity of WPF. And when one team decides about the development stack for the brand new desktop application, they mainly vote for WPF. On the other hand, there are demands for WinForms applications when it is needed to upgrade existing software which is tightly coupled with WinForms, demands for higher performance, etc.

Different approaches

There are many opinions on the subject about testable WinForms apps. Some claim that it's not possible to test WinForms apps because there is a lot of dependency between user events and business logic.

Standard windows form contains Designer.cs partial class and a partial class which contains event handlers for user actions.  So, if we follow this same principle and try to implement app logic in event handlers, we can conclude that it would be very hard to write tests for this kind of application. But, if we look at this problem from some distance we can conclude that every application with user interface could be represented as an interaction between 3 main components:  Data, User Interface and Business Logic.

This is the basic idea of MV* patterns. If we succeed to segregate these three components, then our application is on a good way to be testable. I made a simple WinForms app using MVP pattern. The entire project could be downloaded from here.

In this article, I would just use code snippets to give the general idea how the code looks like.

But first, few words about MVP pattern

MVP stands for Model-View-Presenter. Model is a component that contains data. It is just data holder for our forms. View represents the User Interface. It contains design description of our form.
Presenter is a component that does most of the job in our WinForms app. It is subscribed to view events and those events are results of user interaction with our form (clicks on buttons, text change, selection change, etc.) and OS interaction with our form (load, show, paint etc.) Presenter needs to handle all these events and, after their processing, make appropriate action on the view.

Code structure

Let start with our view component.

We created an interface IProductView that defines rules how Presenter and User Interface component will interact.

Now, let take a look at our presenter component.

Our presenter takes  IProductView interface in its constructor. By this way, our view (form) can easily be replaced with another view which implements the same interface. Also, when it comes to mocking, we can easily inject this dependency thru constructor. Another component is  IProductDataAccess which represents database interface.


One test case example

This test case shows how we can easily mock external dependencies in Presenter component.



Conclusion

This is just a simple example how powerful an architecture that starts with an abstraction can be. It is always better to start with some components on the higher level and then, defining the interfaces, you define rules how those components will interact with each other. 
The entire project with much more tests can be found here. 
Any comments and suggestions are welcome.


Sunday, November 27, 2016

Simple GSON example

Intro

GSON is an open source Java API for serializing and deserializing JSON objects from and to Java objects, developed by Google. A purpose of this article is to provide a simple example how to use this library.

Download

GSON API could be found at maven repository. You can add the following section in your pom.xml in order to download gson.jar

 <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
 </dependency>

Simple Example

For this example, we need a remote storage for our JSON objects. There is a free online tool for faking JSON responses http://www.json-gen.com/

We created simple Employee  JSON object with the following structure.

{
  "id": 149859,
  "first_name": "Mike",
  "last_name": "Gonzalez",
  "date": "11/23/2016, 9:11:04 PM",
  "photo": "http://srcimg.com/100/150",
  "married": true
}







This JSON structure can be accessed via next link
 http://json-gen.com/rest/service/get/vpMW0my7SXDmOmTNu795zDeJRn

We also need a class that will represent our Employee JSON object:

As we can see, naming conventions for JSON object and Java object are not the same, so we cannot use default GSON deserializer. For that purpose, we need to create a new class that will implement our logic for deserializing.


And finally, code for main class: