Aug 28

Ever since I started using TDD (test driven development) methods in my work, I never stopped. I rarely start a project without knowing how I’ll test it, and not just in Java: C#, Objective-C, and Python as well. I’ve found that TDD can be done in the most unlikely places, such as servlets using Cactus or Java EE using MockRunner.

However, when I started working with Project Darkstar recently, it seemed impossible to test. Mostly, because it requires you to use their interface, ManagedReference, to contain references between serialized objects (you can decide not to use them, but then performance goes down significantly). The problem is not with the interface but with the way it’s created, which is only by using the DataManager they provide, using the AppContext.getDataManager() method.

This is a problem, because to keep a ManagedPlayer object which holds a reference to a ManagedWeapon, you might have the code:


public final class ManagedPlayer implements ManagedObject, Serializable {
  private ManagedReference<ManagedWeapon> weapon;

  public void setWeapon(ManagedWeapon weapon) {
    // alert early-on that this object is going to change; prevents
    // collisions later.
    AppContext.getDataManager().markForUpdate(this);
    // sets the weapon as a managed reference
    this.weapon = AppContext.getDataManager().createReference(weapon);
  }

  // ... the rest of the class

}

Within the Darkstar runtime context, this works great. However, within a JUnit context, this will fail as AppContext.getDataManager() will return null, and the code will throw an NPE.

For that reason, I have created a set of mocks, and I thought I’d share them in case someone wants to make this into a bigger project, Mockstar or something.

First, I created an interface to abstract everything to do with ManagedReference. Since ManagedObject is just a marker interface, I don’t care much about it; however, the creation of ManagedReference, and the creation of the scalable versions of Set and Map (ScalableHashSet and ScalableHashMap, respectively):


public interface ManagedFactory {
  <T> ManagedReference<T> createReference(T item);
  void markForUpdate(Object item);
  <T> Collection<T> createCollection();
  <T, K> Map<T, K> createMap();
}

Now, the previous code could be written as:


public final class ManagedPlayer implements ManagedObject, Serializable {
  private ManagedFactory factory; // initialized in ctor
  private ManagedReference<ManagedWeapon> weapon;

  public void setWeapon(ManagedWeapon weapon) {
    factory.markForUpdate(this);
    this.weapon = factory.createReference(weapon);
  }

  // ... the rest of the class

}

The following are the implementations of MockManagedReference, DarkstarManagedFactory and MockManagedFactory:

MockManagedReference

Note that this class is serializable as to not break the original ManagedReference’s implementation’s intention.


public class MockManagedReference<T> implements ManagedReference<T>, Serializable {
    private static int globalId = 1;
    private T item;
    private int id;

    public ManagedReferenceMock(T item) {
        this.item = item;
        this.id = globalId++;
    }

    public T get() {
        return item;
    }

    public T getForUpdate() {
        return item;
    }

    public BigInteger getId() {
        return BigInteger.valueOf(id);
    }
}

DarkstarManagedFactory

This class is the one you would really use in the Darkstar context.


public final class DarkstarManagedFactory implements ManagedFactory {
    public <T> ManagedReference<T> createReference(T item) {
        return AppContext.getDataManager().createReference(item);
    }

    public void markForUpdate(Object item) {
        AppContext.getDataManager().markForUpdate(item);
    }

    public <T> Collection<T> createCollection() {
        return new ScalableHashSet<T>();
    }

    public <T, K> Map<T, K> createMap() {
        return new ScalableHashMap<T,K>();
    }
}

MockManagedFactory

This class will be used in a unit testing context.


public class ManagedObjectFactoryMock implements ManagedObjectFactory {
    public <T> ManagedReference<T> createReference(T item) {
        return new ManagedReferenceMock<T>(item);
    }

    public void markForUpdate(Object item) {
        // empty.
    }

    public <T> Collection<T> createCollection() {
        return new HashSet<T>();
    }

    public <T, K> Map<T, K> createMap() {
        return new HashMap<T,K>();
    }
}

Conclusion

I couldn’t find anything in my searches for a mock system for Darkstar. If someone knows of any, please let me know. On the other hand, if someone actually does something with what I wrote, I would be even more interesting in knowing!

Jul 19

Know the feeling when you’re just about to release code to the public’s eye, and all you need to do is write that pesky build file? Even as I write it I feel it’s an understatement: the task of creating an ant build file can take a few good days out of anyone’s life, and even with copying the last project’s build file and changing a few parameters you can’t really minimise it to less than half a day’s work. 

Continue reading »

May 24

I’m having a lot of problems with the server lately. Many people have complained that they have tried to leave comments unsuccessfully, I hear that the RSS feeds sometimes don’t work, and even my own management is sometimes blocked off.

I am figuring out the steps I should take - upgrade my current hosting plan or switch to a different host - and a resolution should be available soon.

For those of you who try to leave comments: try, try again! If a comment is sent out twice, I will just remove it myself; please don’t let this prevent you from sending them.

In the meantime, my sincere apologies for the inconvenience.

Chaotic Java is Digg proof thanks to caching by WP Super Cache!