TLDR: я хотел бы знать, как расширить fit.TypeAdaptor, чтобы я мог вызывать метод, который ожидает параметры, поскольку реализация TypeAdaptor по умолчанию вызывает связанный (связанный?) метод путем отражения и предполагает, что это метод без параметров...
Более длинная версия. Я использую fit для создания тестовой системы для своей системы (служба, которая возвращает отсортированный список пользовательских объектов). Чтобы проверить систему, я решил использовать fit.RowFixture для утверждения атрибутов элементов списка.
Поскольку RowFixture ожидает, что данные будут либо общедоступным атрибутом, либо общедоступным методом, я подумал об использовании оболочки для своего пользовательского объекта (скажем, InstanceWrapper) — я также попытался реализовать предложение, данное в эта предыдущая тема о форматировании данных в RowFixture.
Проблема в том, что мой пользовательский объект имеет около 41 атрибута, и я хотел бы предоставить тестировщикам возможность выбирать, какие атрибуты они хотят проверить в этом RowFixture. Кроме того, если я динамически не добавляю поля/методы в свой класс InstanceWrapper, как RowFixture будет вызывать любой из моих геттеров, поскольку оба ожидают, что имя атрибута будет передано в качестве параметра (код скопирован ниже)? Я расширил RowFixture для привязки к моему методу, но я не уверен, как расширить TypeAdaptor, чтобы он вызывался с именем attr. Любые предложения?
public class InstanceWrapper {
private Instance instance;
private Map<String, Object> attrs;
public int index;
public InstanceWrapper() {
super();
}
public InstanceWrapper(Instance instance) {
this.instance = instance;
init(); // initialise map
}
private void init() {
attrs = new HashMap<String, Object>();
String attrName;
for (AttrDef attrDef : instance.getModelDef().getAttrDefs()) {
attrName = attrDef.getAttrName();
attrs.put(attrName, instance.getChildScalar(attrName));
}
}
public String getAttribute(String attr) {
return attrs.get(attr).toString();
}
public String description(String attribute) {
return instance.getChildScalar(attribute).toString();
}
}
public class MyDisplayRules extends fit.RowFixture {
@Override
public Object[] query() {
List<Instance> list = PHEFixture.hierarchyList;
return convertInstances(list);
}
private Object[] convertInstances(List<Instance> instances) {
Object[] objects = new Object[instances.size()];
InstanceWrapper wrapper;
int index = 0;
for (Instance instance : instances) {
wrapper = new InstanceWrapper(instance);
wrapper.index = index;
objects[index++] = wrapper;
}
return objects;
}
@Override
public Class getTargetClass() {
return InstanceWrapper.class;
}
@Override
public Object parse(String s, Class type) throws Exception {
return super.parse(s, type);
}
@Override
protected void bind(Parse heads) {
columnBindings = new TypeAdapter[heads.size()];
for (int i = 0; heads != null; i++, heads = heads.more) {
String name = heads.text();
String suffix = "()";
try {
if (name.equals("")) {
columnBindings[i] = null;
} else if (name.endsWith(suffix)) {
columnBindings[i] = bindMethod("description", name.substring(0, name.length()
- suffix.length()));
} else {
columnBindings[i] = bindField(name);
}
} catch (Exception e) {
exception(heads, e);
}
}
}
protected TypeAdapter bindMethod(String name, String attribute) throws Exception {
Class partypes[] = new Class[1];
partypes[0] = String.class;
return PHETypeAdaptor.on(this, getTargetClass().getMethod("getAttribute", partypes), attribute);
}
}