Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

27 December 2016

An XmlResult for ASP.NET MVC


Introduction

ActionResult methods in a Controller allow developers to easily return HTML results and JSON results via this.View(...) which creates a ViewResult and this.Json(...) which creates a JsonResult. [See the following MSDN resources for more information: Controller.View method and Controller.Json method.]

Unfortunately, there is no XmlResult type that derives from ActionResult.

Although there are WCF ways of returning XML in an ASP.NET MVC application, there are use cases where returning simple POX (plain old XML) from a call to an MVC Controller ActionResult is needed.

In this article, I'll show a simple way to create an XmlResult.



How to create an XmlResult


Requirements

An XmlResult should

  • Inherit from ViewResult,
  • Override the ExecuteResult method to write the XML,
  • Expose the object to serialize as a gettable property, and
  • Allow calling code to customize the XML produced.

The ExecuteResult override should

  • Do nothing if there is no object to serialize,
  • Use the XmlAttributeOverrides if there are any,
  • Set the ContentType of the Response to application/xml, and
  • Write the XML-serialized version of the object to serialize to the Output stream of the Response.



XmlResult Code

Below is code that meets these requirements:





How to extend Controller to easily return an XmlResult

It is desirable to be able to have an ActionResult method in a Controller be able to obtain an XmlResult via a this.XML(...) statement.

This can be accomplished via an Extension Method.


Requirements

The Controller.XML extension method should

  • Accept an object to serialize,
  • Optionally accept XmlAttributeOverrides, and
  • Return an XmlResult.


Code


Below is code that meets these requirements:




Conclusion

This article shows a simple way to create an XmlResult to return XML that can be used within an ASP.NET MVC Controller, and a way to extend Controller to allow for easy use.

This approach is appropriate for simple needs and eliminates the need to write custom code each time XML is needed.

For more complicated needs, using a ContentResult offers a feasible approach.

23 December 2016

How to unit test an interface to make certain that it does not get changed


When and why Interface invariance matters

Agile principles teach us that program code should rely on and hold references to abstractions. In C#, this often means declaring a field, a property, an argument or a return type as an interface.

Agile also teaches us when building packages and multi-tier applications to let the client/consumer dictate the interface (logic-to-interface in SOA terms).

If an interface is only consumed within a single application, invariance isn't such a big concern. When interfaces are used by other applications or other packages, however, we must consider them as "published" and treat them as unchanging contracts (see Martin Fowler's article in IEEE Software March/April 2002 for more on this at http://martinfowler.com/ieeeSoftware/published.pdf).

It is important to note that not all interfaces need to be invariant.

Unit Testing for Interface Invariance

Using NUnit's ability to run the same suite of tests on multiple types via its TestFixture with Type and constructor parameters, it is fairly straight-forward to construct a unit test that ensures that an interface only has certain properties and methods.

Our approach will still be the traditional "Arrange/Act/Assert" unit testing pattern, but to eliminate repetitive code, the arrange and act steps will happen in the constructor for the test fixture.

This yields a test fixture ctor with a signature like the following:


There are many ways to approach interface testing. The approach that we favor is to simply test the signatures of properties and methods, optionally ignoring "Special Name" methods, which excludes "get" and "set" methods that properties generate behind the scenes. If you need to test for a read-only property, simply set the constructor parameter ignoreSpecialNames to false.

Arrange & Act


Arrange

We are going to perform the "arrange" part of the unit tests by using NUnit's injection feature via the TestFixture.

To accomplish this, first declare the test fixture class like this:


public class InterfaceContractTests<T> : AssertionHelper where T : class

Next, add test fixture attributes similar to the following (the first argument sets the type T; the remaining are the constructor arguments):

  • Testing for just a method

    [TestFixture(
      typeof(IOutput),
      new string[] { "Void Write(System.String)" },
      new string[] { },
      true,
      null)]

  • Testing for properties, get/set and inheritance

    [TestFixture(
      typeof(IColorOutput),
      new string[]
      {
        "System.String get_Color()",
        "Void set_Color(System.String)",
        "System.String get_BackgroundColor()"
      },
      new string[]
      {
        "System.String Color",
        "System.String BackgroundColor"
      },
      false,
      typeof(IOutput))]

Act

Our code needs to test each property and method to ensure that it is declared by the type we are testing. This is done by checking the DeclaringType property of the MethodInfo and PropertyInfo objects that are returned when our code calls the methods to get the public properties and public methods of the interface.

If our tests are not checking for read-only properties, we can exclude the "get" and "set" methods by testing if the IsSpecialName property of the MethodInfo object is true.

The code for getting the actual method and property signatures is shown below.


Full Constructor Code

Below is the full code for the resulting constructor.


Assert

There are four tests that need to be run for each interface:

  • Verify that we're testing an interface,
  • Verify that the actual method signatures match expectations,
  • Verify that the actual property signatures match expectations, and
  • Verify that the interface does or does not extend another interface.

Below is the code that implements these tests.


Conclusion

When interfaces are used by independent components or clients, they should be considered to be "published" and invariant.

Interfaces that are invariant should have unit tests that ensure that they do not change and break the published contract.

This article shows an easy-to-use and repeatable testing approach that ensures interface invariance. If you add it to your suite of tests and update it as new published interfaces are authored, you will reduce your risk of bugs and broken code.

21 December 2016

How to adjust base class tests to test derived classes using NUnit

One of the categories of hard to chase down bugs I often see in C#.NET code is caused by violation of the Liskov Substitution Priniciple. In this post, I'll show a quick way to adapt NUnit unit tests for a base class to also test a derived class.

Liskov Substitution Principle

In a nutshell, LSP requires that derived types when substituted for their base types should behave in exactly the same way.

The Problem

In modern applications, it is fairly common to see inheritance implementations that break the LSP rule. If the violation isn't caught and fixed, it is a bug waiting to happen. Eventually, some program code will perform an operation using an object of a type derived from the base class, relying upon it to behave as the base class does. When it does, things will break.

The Rectangle/Square Example of LSP Violation

In geometry, a square is just a special type of rectangle with width and height equal.

Naïvely, a developer may decide to represent this in code as a Square class inheriting from a Rectangle class.

The Solution

The original unit tests for Rectangle at some point create a Rectangle instance.

The first step is to move this instantion into a [SetUp] method in your NUnit [TestFixture]. The setup method runs before every individual test.

The next step is to refactor the test class to be generic; something similar to the following will work:

public class ViolatorTests<TShape> : AssertionHelper where TShape : IRectangle, new().

Next change the setup method to instantiate an instance of the generic type TShape.

With these changes in place, you simply need to change your TestFixture attribute to [TestFixture(typeof(Rectangle))]. This gets you back to your original Rectangle tests.

Finally, to make the base class tests run against the derived type, simply add another TestFixture attribute to the class – this will cause the NUnit framework to run the test suite against the new type specified.

Below is a complete example for the rectangle/square scenario. The test will fail when the derived type Square is used, indicating that you have a violation of LSP and need to rethink how the two classes should be related


Conclusion

By slightly refactoring your NUnit base class unit tests to be generic, you can make them usable for testing derived classes without writing duplicate tests (remember: DRY – Don't Repeat Yourself). This will catch LSP violations early in development and prevent hard to pin down bugs.


06 December 2016


How to test that an ASP.NET MVC Controller Only Accepts an HTTP GET


Test-Driven Development (TDD)

An important agile priniciple is that code only be written in response to a test. Covering unit tests along with continuous integration (CI) allows development to move quickly and be confident that new code will not break old code.



Testing Orthogonal Concerns

The challenge with testing for HTTP Verb limitations is that, to follow the Single Responsibility Principle (SRP), the code limiting the verbs should be an orthogonal concern (i.e. that it should not be directly in the controller method).

Thankfully, ASP.NET MVC allows a developer to limit the HTTP verbs that a controller accepts via an Attribute.

How to verify that a method has an Attribute

Since ASP.NET MVC development uses managed languages, Reflection allows a test author to verify that an attribute has been applied.

Suppose one wants to test the following method for the presence of an HttpGet attribute:


The process for testing for an attribute is simple.

  1. Get a reference to the type.
  2. Get a reference to the method.
  3. Get a reference to the custom attribute.
  4. Test that the reference is not null (i.e. that the attribute was applied to the method)


Code

Below is code showing how to test for the presence of an attribute on a method.


Below is a more complicated example which tests that the attribute is configured in a certain way.




05 October 2012

The first rule of multi-threading is "DON'T MULTI-THREAD".

Sometimes, however, there are long-running operations which need to be allowed to run without freezing the UI.

The QueueUserWorkItem method is a convenient way to execute a method while the .NET framework manages the threading. The traditional challenge has been the method signature for the function that is passed — it takes one parameter of type object (you can create a type, modify the signature, etc., but it has always seemed unnatural modifying signatures to accommodate the threading apparatus.)

Dynamic types are an alternative approach

Suppose you have code like that found below.

private void ProcessQueue(string jobId, string vaultName, string outputPath) { // ... }

One way to make it work with the WaitCallback signature is to create an overload that accepts a dynamic parameter (shown below)

public void ProcessQueue(dynamic obj) { this.ProcessQueue(obj.jobId, obj.vaultName, obj.outputPath); }

This overload calls the original method. The advantage to the approach is that it does not require the creation of a new type. The call can be made using an anonymous type as shown below.

System.Threading.ThreadPool.QueueUserWorkItem( this.ProcessQueue,
new { jobId = jobId, vaultName = vaultName, outputPath = "..." } );

Quicker. More natural IMHO.

23 August 2011


namespace CSVtoExcel
{
 using System;
 using Excel = Microsoft.Office.Interop.Excel;
 using File = System.IO.File;
 using Path = System.IO.Path;
 class Program
 {
   static void Main(string[] args)
   {
     if (args.Length == 0)
     {
       throw new ApplicationException("Missing file name");
     }
     string file = args[0];
     if (!File.Exists(file))
     {
       throw new System.IO.FileNotFoundException("File specified in command line not found", file);
     }
     var app = new Excel.Application() { DisplayAlerts = false };
     try
     {
       app.Workbooks.Open(file);
       app.ActiveWorkbook.SaveAs(
         Path.ChangeExtension(file, "xls"),
         FileFormat: Excel.XlFileFormat.xlWorkbookNormal,
         ConflictResolution: Excel.XlSaveConflictResolution.xlLocalSessionChanges);
     }
     finally
     {
       app.Quit();
     }
   }
 }
}