views:

71

answers:

2

I am developing a simulator for a machine. It reads a file in, stores it in a string (as a binary number) to an array that is supposed to simulate the memory of a computer. Then it gets passed to an interpreter that takes gets the first element of the array, and based on the first 4 characters it gets sent to another class.

An example of one of those classes is below:

public class Add {
private String cell;

Add() {
    cell = null;
}

/**
 * Method that performs the operation add.
 */
public void addition() {
    // TODO Figure out 2's complement.
    Loader instance = Loader.Instance();
    cell = instance.getCell();

    Integer DR1num = Integer.parseInt(cell.substring(4, 6), 2);
    Integer SR1num = Integer.parseInt(cell.substring(7, 9), 2);

    if (cell.charAt(10) == '0') {
        Integer SR2num = Integer.parseInt(cell.substring(13, 15), 2);
        Integer addedval = instance.getRegister(SR1num)
                + instance.getRegister(SR2num);
        instance.setCCR(addedval);
        instance.setRegister(DR1num, addedval);
    } else if (cell.charAt(10) == '1') {
        Integer immediate = Integer.parseInt(cell.substring(11, 15), 2);
        Integer addedval = instance.getRegister(SR1num) + immediate;
        instance.setCCR(addedval);
        instance.setRegister(DR1num, addedval);
    } else {
        System.err.println("Invalid Char at Position 10. Expected 0 or 1");
    }

    instance.incrementPC();

}

public String getcell() {
    return cell;
}

}

Variable Descriptions: instance is the singleton cell is the binary string that is stored in the memory array DR1num is Destination Register. (aka R0, R1, ... R7) SR1num is Source Register

What this operation does is takes either two Source Registers and adds them together (then sets the Condition Code Register if it is positive, negative, or zero), or takes a Source Register and an immediate value and adds those two together. The result is stored in the Destination Register.

I chose to use a singleton class because I need the Memory, General Purpose Registers, Condition Code Register, and Program Counter to be in sync throughout the entire program. The problem that this presents is that I have no idea how to test my program (preferably with jUnit).

The only way I can think of testing the program is by writing a bunch of individual files for the program to read in. Except this means that instead of testing only one part of my program, at a minimum it tests three classes. The class that reads in the program and contains all the methods for the singleton, the class that determines which class to call, and finally the class that actually executes that portion (such as Add).

Does anyone have any suggestions for a better way to test?

+5  A: 

The way to avoid this is traditionally to use inversion of control (IoC) and inject an instance of your singleton class into the client class. Your client class is provided with all the dependent classes it requires to function, and not concerned with the lifecycle of the dependent classes.

Spring is the common Java framework used to do this, but you can inject simply by constructing your class with a reference to the singleton (it's that simple).

If the singleton class implements an interface then testing is made easier since you can inject mock variants rather than the real implementation, and build your mock to provide suitable test data for your tests.

Brian Agnew
Obligatory: "Singletons are pathological liars" http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project.html and "Where have all the Singletons gone?" http://misko.hevery.com/2008/08/21/where-have-all-the-singletons-gone/
matt b
Guice is also a great DI library, and focused on DI only.
ColinD
@Matt - nice links. Thx
Brian Agnew
A: 

I think you can test it if the loader is an interface and then by using mocking frameowork like EasyMock you can insert the mocked class instance instead of the actual instance.

This will work if the Loader is an interface

Shekhar