Testing and Internal Implementation in .NET

Switching back and forth between Java and .NET lets you see some of the differences between the two platforms more easily. This happened to me the other day when I switched from Java to .NET and was writing Unit Tests. In Java, the access modifiers include public, private, protected and default. In C# they are public, private, protected and internal. In general, the public, private access modifiers are very similar. Protected is slightly different in that Java allows both derived classes as well as classes in the same package to access those elements where C# only allows derived classes to access them. Where things diverge more is in the default/internal differences. Default in java restricts access to the same package while internal in C# restricts access to the same Assembly (generally a single DLL).

What does this have to do with testing you might ask?

It’s a good OO design principle to expose only those things that are part of the contract to a class or package and to leave the implementation hidden as much as possible. This is called encapsulation. You can make methods private or default/internal. You can make entire classes default/internal and only publicly expose an interface that clients need to use.

A common practice in the Java world is to mimic the package layout of your main source code in your test code. When you mimic that layout then your test classes and implementation classes end up being in the same packages. Because of this your test classes can access all those default members to test them. In C# because it’s not based on a namespace, but rather an Assembly this doesn’t work.

Luckily there’s an easy workaround.

In the AssemblyInfo.cs of your main project add:

[assembly: InternalsVisibleTo("someOther.AssemblyName.Test")]

Where SomeOther.AssemblyName.Test is the name of the Assembly that contains your tests for the target assembly. Then the test code can access internal details of the assembly. And you can easily test the things that other calling code might not have access to.

Scheme/HtDP Unit Testing Functions

How to Design Programs (HtDP) provides a series of unit testing functions that allow you to test the output of any kind of function. The current version talks about testing your code, but doesn’t offer a lot of guidance into how to do that. Everything you need is there though, so in case you are doing this on your own and don’t have a teacher to tell you to do this, here’s some explanation that I hope helps.

check-expect

check-expect takes the results of a function and the expected value. This is the simplest of the testing constructs which answers the question “Does the expected result of a function call equal the result returned by the function?”. It handles all of the details about types of values returned, so it can work with a simple value like a number, a complex value like a structure or a list, or even a picture.


;; add: number number -> number
;; add two numbers together
(define (add n m)
(+ n m))

;; Tests
(check-expect (add 1 1) 2)

check-within

check-within is similar to check-expect, but it allows for a third argument to tell wether or not the result is within a certain difference of the actual answer. This is good for certain functions that might produce random results, but the most common case is when dealing with floating point numbers. Floating point numbers are not always represented precisely, so there needs to be some “room for error” so to speak.


(define PI 3.14)
(check-within (/ 22 7) PI .003)

(check-within (random 10) 0 9)

check-error

Finally, you can use check-error to test cases where your function throws an error. Those error conditions are an important part of a function contract, so testing them should be done just like any other possible conditions.

One of the things that threw me at first was what to use as the expected value of a check-error test.

An error is HtDP is “throw” by a function like:

(error 'function-name "some message")

After a bit of trial and error, I found out the expected result is a string like:

; "function-name: some message"
(check-error (error 'list-pick "list too short") "list-pick: list too short")

More Realistic Example


;; list-pick : list-of-symbols N[>= 0] -> symbol
;; to determine the nth symbol from alos, counting from 0;
;; signals an error if there is no nth item
(define (list-pick alos n)
(cond
[(empty? alos) (error 'list-pick "list too short")]
[(= n 0) (first alos)]
[(> n 0) (list-pick (rest alos) (sub1 n))]))

;; Tests
(check-error (list-pick empty 1) "list-pick: list too short")
(check-expect (list-pick (list 'a 'b 'c 'd) 3) 'd)
(check-error (list-pick (list 'a 'b 'c 'd) 4) "list-pick: list too short")

Grails Testing Acegi Security

Almost every web application I create needs some form of user authentication and authorization. Grails provides a great plugin system that allows you to extend the base framework to provide these kinds of features. My current favorite security plugin for Grails is the Acegi Security Plugin. It’s built using the Spring Security framework and the robust and widely used Acegi framework. I like the fact that it is built on top of existing, well-known frameworks which is the philosophy of Grails itself. It is also a flexible plugin that has a good default object model.

One of the situations that inevitably arises is how to unit test code that depends on your security framework. Either you will want to test that basic authorization is working, or you might have code that makes decisions based upon who is logged in or what roles they might have. To run those test you have to setup your test cases so that the code that works when the system is running normally is tested.

Unit Testing Setup for Testing Acegi Security Code

This situation arose for me the other day and so I thought I would share the solution that I came up with.


import org.springframework.security.context.SecurityContextHolder as SCH
import org.springframework.security.providers.TestingAuthenticationToken
import org.springframework.security.GrantedAuthority
import org.springframework.security.Authentication
import org.springframework.security.GrantedAuthorityImpl

class AuthenticationBaseTests extends GroovyTestCase {
def setUp() {
def user = User.get(1) // or create a new one if one doesn't exist
authenticate(user, "abc123", [new GrantedAuthorityImpl('ROLE_ADMIN')])
}

protected Authentication authenticate(user, credentials, authorities) {
def principal = new Expando()
principal.domainClass = user

Authentication authentication = new TestingAuthenticationToken(principal, null, authorities as GrantedAuthority[])
authentication.authenticated = true
SCH.context.authentication = authentication
return authentication
}
}

setUp()

The setUp() method will get executed prior to your tests being run. So if you want to do different things for each test you would want to move this code to a more appropriate place. In the setup method we are creating our Principle class, in this case, the User. Next we pass the user along with all of the roles we want the user to have for the given test case.

authenticate(user, credentials, authorities)

The real setup work is done in the authenticate() method. This method does the real work of setting up the Authentication Token and setting it in the static context, which is a thread local variable I think, that is used by the framework to determine who is making the request and what rights they have.

The fun thing about this message is the use of the Expando class. Expando allows you to create a class on the fly. This is a really interesting way to do a Mock object on-the-fly in Groovy. In this case we’re creating a Mock authentication principle. We know, by looking at the Acegi Security code, that the security framework expects an object that will call domainClass to get the underlying implementation of the User (or Principle) implemented in the application. That will return us the User object that we are setting.

This simple method can be added to a base class and then inherited from any tests that need user authentication to run successfully.