-
-
Notifications
You must be signed in to change notification settings - Fork 2
Code Reuse and Testing
The main goal of this library was to facilitate testing, maintaining, and perhaps even reusing the logic within your LDAP filters. Read on to get a rough idea of how you might accomplish this.
In Linq2Ldap.ExampleCommon, there is an implementation of the Specification pattern (in case you don't already have your own) to wrap your Expressions and improve code reuse and testability. It facilitates the otherwise abstruse ability to glue your Expressions together with And and Or.
using Linq2Ldap.ExtensionMethods;
using Specifications;
// ...
public class MyBizSpecifications {
public virtual Specification<User> ActiveUsers() {
return Specification<User>.Start(
u => u.Status == "active"
&& ! u.Suspended.Matches("*") /* not exists */
);
}
public virtual Specification<User> UsersInCountry(string country) {
return Specification<User>.Start(u => u.Country == country);
}
public virtual Specification<User> ActiveUsersInCountry(string country) {
return ActiveUsers().And(UsersInCountry(country));
}
// ...
}
Drawing from the example, above, if you want to unit test your filter logic, you can now write tests like this:
public class MyBizSpecificationsTests {
public MyBizSpecifications Specs;
public MyBizSpecificationsTests() {
Specs = new MyBizSpecifications();
}
[Fact]
public void ActiveUsers_ExcludesSuspended() {
// Setup
var users = new List<User>() {
new User() { Id = "oneuser", Status = "active", Suspended = "some reason" },
new User() { Id = "twouser", Status = "active", Suspended = null }
}.AsQueryable();
var spec = Specs.ActiveUsers();
// Run
var subset = users.Where(spec).ToList();
// Inspect
Assert.Equal(users.ElementAt(1), subset.FirstOrDefault());
}
}
The alternative is either integration-testing your expressions against an LDAP server, which can be slow, shallow, and hard to implement, or--worse--manually testing them, which, with even just a few, would be like trying to maintain a sandcastle in the tide.