Unit testing Stripes ActionBeans

There are two ways for unit testing Stripes applications: directly instantiate the ActionBean or use Mock objects. But neither provided the “feel” I wanted to have for my unit tests.

In my tests I wanted to use a URL only to call the right ActionBean. So, my own solution is a mixture between mocking and direct instantiation. in my tests I use the following method to create an ActionBean:


    protected <T extends ActionBean> T createActionBean(String url, Class<T> clazz, Map<String, Object> params)
            throws Exception {

        T instance = clazz.newInstance();
        injectMembers(instance);

        UrlBindingFactory factory = UrlBindingFactory.getInstance();
        factory.addBinding(clazz, UrlBindingFactory.parseUrlBinding(clazz));
        UrlBinding binding = factory.getBinding(url);

        Method method = null;

        for (UrlBindingParameter parameter : binding.getParameters()) {
            String name = parameter.getName();
            if (name.equals("$event")) {
                if (parameter.getValue() != null) {
                    method = clazz.getDeclaredMethod(parameter.getValue());
                }
            }
            else {
                Field field = clazz.getDeclaredField(name);
                field.setAccessible(true);
                Validate validate = field.getAnnotation(Validate.class);
                Object value = null;
                if (validate != null) {
                    Class<? extends TypeConverter> converter = validate.converter();
                    if (converter != null) {
                        value = converter.newInstance().convert(parameter.getValue(),
                                field.getType(),
                                new ArrayList<ValidationError>());
                    }
                }
                if (value == null && parameter.getValue() != null) {
                    if (Number.class.isAssignableFrom(field.getType())) {
                        value = DecimalFormat.getNumberInstance().parse(parameter.getValue());
                    }
                }
                field.set(instance, value);
            }
        }

        if (params != null) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                Field field = clazz.getDeclaredField(entry.getKey());
                field.setAccessible(true);
                field.set(instance, entry.getValue());
            }
        }

        if (method == null) {
            for (Method m : clazz.getDeclaredMethods()) {
                if (m.isAnnotationPresent(DefaultHandler.class)) {
                    method = m;
                }
            }
        }
        if (method != null) {
            method.invoke(instance);
        }
        return instance;
    }

What is still missing: I’d like to use the Stripes provided mock object classes more to support all types of parameters, validations etc.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>