使用 Olingo / ODATA 4 编写 ExpressionVisitor 的集成测试
Writing Integration Test of ExpressionVisitor with Olingo / ODATA 4
我正在使用框架 Olingo 以 Java 语言实现 OData 标准第 4 版的 Web 服务。我需要自定义 $filter
的响应。我已经实现了一个访客 as documented in the quick start。我需要实施集成测试以尝试不同类型的语法并防止在未来维护时出现回归错误。
对于 V2,我找到了 the following tutorial 和以下代码:
@Test
public void printExpressionWithProperty() throws Exception {
//Use a mocked edmProvider for this tutorial
TestEdmProvider provider = new TestEdmProvider();
Edm edm = RuntimeDelegate.createEdm(provider);
EdmEntityType entityType = edm.getEntityType(TestEdmProvider.NAMESPACE_1, TestEdmProvider.ENTITY_TYPE_1_1.getName());
String rawExpression = "EmployeeId eq '1'";
FilterExpression expression = UriParser.parseFilter (null, entityType, rawExpression);
String whereClause = (String) expression.accept(new JdbcSimpleStringVisitor());
System.out.println("Raw: " + rawExpression + " ------> Whereclause: " + whereClause);
System.out.println();
}
不幸的是,UriParser.parseFilter
在 v4 中不存在。
我试过这个:
public class MyVisitorTest {
private final FullQualifiedName NAME1 = new FullQualifiedName("testNamespace1", "myfield");
private final OData odata = OData.newInstance();
public EdmEntityType createEntityType(final FullQualifiedName fqn) {
if (NAME1.equals(fqn)) {
EdmEntityType entityType = mock(EdmEntityType.class);
when(entityType.getNamespace()).thenReturn(fqn.getNamespace());
when(entityType.getName()).thenReturn(fqn.getName());
return entityType;
}
return null;
}
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
EdmEntityType entityType = createEntityType(NAME1);
Edm edm = mock(Edm.class);
when(edm.getEntityType(NAME1)).thenReturn(entityType);
final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, null, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(UriTokenizer.TokenKind.EOF));
return expression;
}
@Test
public void simpleTest() throws UriParserException, UriValidationException, ODataApplicationException, ExpressionVisitException {
String exp = "myfield gt 2019-01-01T00:00:00Z";
Expression e = parseExpression(exp);
MyVisitor myVisitor = new MyVisitor();
String result = (String) e.accept(startEndMeasureVisitor);
assertEquals(result.toString(), "MyResult");
}
}
它不起作用,它向我发送了以下消息:
Property paths must follow a structured type.
所以我正在寻找使我的单元测试正常工作的任何想法,或者如果您有工作示例要分享...
谈到单元测试,我会专注于单独测试每个过滤器方法。比如 if visitBinaryOperator
returns 基于输入的期望值等等。
我不是命名专家,但我会将您的测试称为集成测试。在这里,我将重点放在测试FilterOption
内部编写的测试中。在您的原始应用程序中,Apache Olingo 将创建这个 FilterOption
并且这部分(应该)在 Olingo 中进行测试。
当我使用 Apache Olingo 时,我经常提到 its repository,尤其是 server-test 和 server-tecsvc.验证 Olingo 本身是如何测试的。
我建议看一下 FilterValidator,因为它可能对您的集成测试有用。
我们开始吧,感谢模型的跟踪功能(对遗留代码非常有用),我得到了新版本的 parseExpression
方法来回答我的问题。
class A implements EdmStructuredType, EdmPrimitiveType {
@Override
public boolean isCompatible(EdmPrimitiveType edmPrimitiveType) {
return false;
}
@Override
public Class<?> getDefaultType() {
return null;
}
@Override
public boolean validate(String s, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1) {
return false;
}
@Override
public <T> T valueOfString(String s, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1, Class<T> aClass) throws EdmPrimitiveTypeException {
return null;
}
@Override
public String valueToString(Object o, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1) throws EdmPrimitiveTypeException {
return null;
}
@Override
public String toUriLiteral(String s) {
return null;
}
@Override
public String fromUriLiteral(String s) throws EdmPrimitiveTypeException {
return null;
}
@Override
public EdmElement getProperty(String s) {
return null;
}
@Override
public List<String> getPropertyNames() {
return null;
}
@Override
public EdmProperty getStructuralProperty(String s) {
return null;
}
@Override
public EdmNavigationProperty getNavigationProperty(String s) {
return null;
}
@Override
public List<String> getNavigationPropertyNames() {
return null;
}
@Override
public EdmStructuredType getBaseType() {
return null;
}
@Override
public boolean compatibleTo(EdmType edmType) {
return false;
}
@Override
public boolean isOpenType() {
return false;
}
@Override
public boolean isAbstract() {
return false;
}
@Override
public EdmAnnotation getAnnotation(EdmTerm edmTerm, String s) {
return null;
}
@Override
public List<EdmAnnotation> getAnnotations() {
return null;
}
@Override
public FullQualifiedName getFullQualifiedName() {
return null;
}
@Override
public String getNamespace() {
return null;
}
@Override
public EdmTypeKind getKind() {
return null;
}
@Override
public String getName() {
return null;
}
}
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
Edm edm = mock(A.class, withSettings().defaultAnswer(RETURNS_SMART_NULLS));
EdmProperty employeeIdTypeEdmElement = mock(EdmProperty.class, RETURNS_SMART_NULLS);
when(edmType.getProperty("EmployeeId")).thenReturn(measureTypeEdmElement);
when(edmType.getKind()).thenReturn(EdmTypeKind.PRIMITIVE);
when(edmType.isCompatible(new EdmDate())).thenReturn(true);
when(employeeIdTypeEdmElement.getName()).thenReturn("EmployeeId");
when(employeeIdTypeEdmElement.getType()).thenReturn(edmType);
when(employeeIdTypeEdmElement.isCollection()).thenReturn(false);
final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, edmType, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(UriTokenizer.TokenKind.EOF));
return expression;
}
万一对谁有帮助,说不定可以优化一下,随意补充。
我正在使用框架 Olingo 以 Java 语言实现 OData 标准第 4 版的 Web 服务。我需要自定义 $filter
的响应。我已经实现了一个访客 as documented in the quick start。我需要实施集成测试以尝试不同类型的语法并防止在未来维护时出现回归错误。
对于 V2,我找到了 the following tutorial 和以下代码:
@Test
public void printExpressionWithProperty() throws Exception {
//Use a mocked edmProvider for this tutorial
TestEdmProvider provider = new TestEdmProvider();
Edm edm = RuntimeDelegate.createEdm(provider);
EdmEntityType entityType = edm.getEntityType(TestEdmProvider.NAMESPACE_1, TestEdmProvider.ENTITY_TYPE_1_1.getName());
String rawExpression = "EmployeeId eq '1'";
FilterExpression expression = UriParser.parseFilter (null, entityType, rawExpression);
String whereClause = (String) expression.accept(new JdbcSimpleStringVisitor());
System.out.println("Raw: " + rawExpression + " ------> Whereclause: " + whereClause);
System.out.println();
}
不幸的是,UriParser.parseFilter
在 v4 中不存在。
我试过这个:
public class MyVisitorTest {
private final FullQualifiedName NAME1 = new FullQualifiedName("testNamespace1", "myfield");
private final OData odata = OData.newInstance();
public EdmEntityType createEntityType(final FullQualifiedName fqn) {
if (NAME1.equals(fqn)) {
EdmEntityType entityType = mock(EdmEntityType.class);
when(entityType.getNamespace()).thenReturn(fqn.getNamespace());
when(entityType.getName()).thenReturn(fqn.getName());
return entityType;
}
return null;
}
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
EdmEntityType entityType = createEntityType(NAME1);
Edm edm = mock(Edm.class);
when(edm.getEntityType(NAME1)).thenReturn(entityType);
final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, null, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(UriTokenizer.TokenKind.EOF));
return expression;
}
@Test
public void simpleTest() throws UriParserException, UriValidationException, ODataApplicationException, ExpressionVisitException {
String exp = "myfield gt 2019-01-01T00:00:00Z";
Expression e = parseExpression(exp);
MyVisitor myVisitor = new MyVisitor();
String result = (String) e.accept(startEndMeasureVisitor);
assertEquals(result.toString(), "MyResult");
}
}
它不起作用,它向我发送了以下消息:
Property paths must follow a structured type.
所以我正在寻找使我的单元测试正常工作的任何想法,或者如果您有工作示例要分享...
谈到单元测试,我会专注于单独测试每个过滤器方法。比如 if visitBinaryOperator
returns 基于输入的期望值等等。
我不是命名专家,但我会将您的测试称为集成测试。在这里,我将重点放在测试FilterOption
内部编写的测试中。在您的原始应用程序中,Apache Olingo 将创建这个 FilterOption
并且这部分(应该)在 Olingo 中进行测试。
当我使用 Apache Olingo 时,我经常提到 its repository,尤其是 server-test 和 server-tecsvc.验证 Olingo 本身是如何测试的。
我建议看一下 FilterValidator,因为它可能对您的集成测试有用。
我们开始吧,感谢模型的跟踪功能(对遗留代码非常有用),我得到了新版本的 parseExpression
方法来回答我的问题。
class A implements EdmStructuredType, EdmPrimitiveType {
@Override
public boolean isCompatible(EdmPrimitiveType edmPrimitiveType) {
return false;
}
@Override
public Class<?> getDefaultType() {
return null;
}
@Override
public boolean validate(String s, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1) {
return false;
}
@Override
public <T> T valueOfString(String s, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1, Class<T> aClass) throws EdmPrimitiveTypeException {
return null;
}
@Override
public String valueToString(Object o, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1) throws EdmPrimitiveTypeException {
return null;
}
@Override
public String toUriLiteral(String s) {
return null;
}
@Override
public String fromUriLiteral(String s) throws EdmPrimitiveTypeException {
return null;
}
@Override
public EdmElement getProperty(String s) {
return null;
}
@Override
public List<String> getPropertyNames() {
return null;
}
@Override
public EdmProperty getStructuralProperty(String s) {
return null;
}
@Override
public EdmNavigationProperty getNavigationProperty(String s) {
return null;
}
@Override
public List<String> getNavigationPropertyNames() {
return null;
}
@Override
public EdmStructuredType getBaseType() {
return null;
}
@Override
public boolean compatibleTo(EdmType edmType) {
return false;
}
@Override
public boolean isOpenType() {
return false;
}
@Override
public boolean isAbstract() {
return false;
}
@Override
public EdmAnnotation getAnnotation(EdmTerm edmTerm, String s) {
return null;
}
@Override
public List<EdmAnnotation> getAnnotations() {
return null;
}
@Override
public FullQualifiedName getFullQualifiedName() {
return null;
}
@Override
public String getNamespace() {
return null;
}
@Override
public EdmTypeKind getKind() {
return null;
}
@Override
public String getName() {
return null;
}
}
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
Edm edm = mock(A.class, withSettings().defaultAnswer(RETURNS_SMART_NULLS));
EdmProperty employeeIdTypeEdmElement = mock(EdmProperty.class, RETURNS_SMART_NULLS);
when(edmType.getProperty("EmployeeId")).thenReturn(measureTypeEdmElement);
when(edmType.getKind()).thenReturn(EdmTypeKind.PRIMITIVE);
when(edmType.isCompatible(new EdmDate())).thenReturn(true);
when(employeeIdTypeEdmElement.getName()).thenReturn("EmployeeId");
when(employeeIdTypeEdmElement.getType()).thenReturn(edmType);
when(employeeIdTypeEdmElement.isCollection()).thenReturn(false);
final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, edmType, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(UriTokenizer.TokenKind.EOF));
return expression;
}
万一对谁有帮助,说不定可以优化一下,随意补充。