I'm writing a fluent API to validate key:value
pair in a Map. I have a hierarchy of validator types. I referred to one answer from Fluent API with inheritance and generics.
public interface IValidator {
IValidator assertValue(String key, String expectedValue) throws Exception;
abstract class Abstract implements IValidator {
protected final Map<String, String> resultMap = new HashMap<>();
@Override
public <T extends IValidator> T assertValue(String key, String expectedValue) throws Exception {
...
return (T) this;
}
}
The 2nd level abstract subclasses redefine the parent type as follows.
public abstract class AbstractValidator
extends IValidator.Abstract {
// other logic not related to assertion
}
The concrete subclasses redefine the parent type similarly.
public class ExampleValidator
extends AbstractValidator
{
public ExampleValidator assertPromptId(String expectedValue) throws Exception{
assertValue(PROMPT_ID, expectedValue);
return this;
}
public ExampleValidator assertNameSpace(String expectedValue ) throws Exception{
assertValue(NAMESPACE, expectedValue);
return this;
}
@Override
public ExampleValidator assertValue(String key, String expectedVlaue) throws Exception {
super.assertValue(key, expectedVlaue);
return this;
}
Now, my test case is as follows. My issue is .withValidator(Ivalidator validator)
was not able to find method of assertPromptId()
and assertNameSpace()
but only assertValue()
. So how to fix it?
public class AssertionContext {
public <T extends IValidator> T withValidator(IValidator validator) throws Exception {
return (T) validator;
}
}
// test method in main
public void invocationTest() throws Throwable {
AssertionContext verify = new AssertionContext();
verify.withValidator(new ExampleValidator()).assertNameSpace("...");
}