如何模仿apache-camel EL

时间:2015-02-25 18:31:59

标签: unit-testing junit apache-camel mockito

我有以下RouteBuilder。

 public class MyRoute extends RouteBuilder {    

        @Override
        public void configure() {
            errorHandler(deadLetterChannel(errorHandlerEndpoint)
                    .maximumRedeliveries(1)
                    .redeliveryDelay(2000)
                    .retryAttemptedLogLevel(LoggingLevel.WARN));

        from(fromEndpoint).routeId("fetchPreprocessingResultFromMarklogicRoute")
         .setHeader("principal").method(principalService, "getPrincipal").id("getPrincipalServiceMethod") // put principal to header for latter use
         .multicast()
            .filter(xpath("//files[@ml-generated='true']"))
            .choice()
                    .when(PredicateBuilder.isEqualTo(constant(EPrincipal.VETCENTER.principal()), simple("${header.principal.principal.principal}")))
                        .log("Sending VetCenter preprocessing report...")
                        .inOnly(toVetCenterEmailNotificationEndpoint)
                    .when(PredicateBuilder.isEqualTo(constant(EPrincipal.OSTEOTHEK.principal()), simple("${header.principal.principal.principal}")))
                        .log("Sending Osteothek preprocessing report...")
                        .inOnly(toOsteothekEmailNotificationEndpoint)
                    .otherwise()
                        .log("Principal unknown. Don't sending a preprocessing report...")
                        .inOnly("direct:trash") // @ToDo: Write test
                .end()
                .inOnly(toCleaningPhaseDecisionEndpoint)
                .inOnly(deleteImportDirsEndpoint)
            .end();

        }
}

这是JUnit-Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-context-test.xml"}) 
public class FetchPreprocessingResultFromMarklogicRoute_Test extends CamelTestSupport{
    private RouteBuilder route;

    @Value("${fetchPreprocessingResultFromMarklogicRoute.fromEndpoint}")
    private String testFromEndpoint;

    @Value("${fetchPreprocessingResultFromMarklogicRoute.toCleaningPhaseDecisionEndpoint}")
    private String toCleaningPhaseDecisionEndpoint;
    @Value("${fetchPreprocessingResultFromMarklogicRoute.vetcenter.toEmailNotificationEndpoint}")
    private String toEmailNotificationVetCenterEndpoint;
    @Value("${fetchPreprocessingResultFromMarklogicRoute.osteothek.toEmailNotificationEndpoint}")
    private String toEmailNotificationOsteothekEndpoint;
    @Value("${fetchPreprocessingResultFromMarklogicRoute.deleteImportDirsEndpoint}")
    private String testDeleteImportDirsEndpoint;
    @Value("${fetchPreprocessingResultFromMarklogicRoute.errorHandlerEndpoint}")
    private String testErrorHandlerEndpoint;

    private MockEndpoint emailNotificationVetCenterMOCKEndpoint;
    @Mock
    private PrincipalService principalServiceMOCK; 

    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        if(route == null){

            route = new MyRoute(
                    testFromEndpoint, 
                    toCleaningPhaseDecisionEndpoint,
                    toEmailNotificationVetCenterEndpoint,
                    toEmailNotificationOsteothekEndpoint,
                    testDeleteImportDirsEndpoint, 
                    testErrorHandlerEndpoint,
                    principalServiceMOCK);
        }
        return route;
    }

    @Override
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        Principal principal = new Principal();
        principal.setPrincipal(EPrincipal.VETCENTER);

        Mockito.when(principalServiceMOCK.getPrincipal("anyIdentificator")).thenReturn(principal);
        super.setUp();
    }


    @Test
    public void test() throws InterruptedException{
        InputStream resourceInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("testdata/importreport/inc/import-log-Vetcenter.xml");
        String message = new Scanner(resourceInputStream).useDelimiter("\\A").next();
        emailNotificationVetCenterMOCKEndpoint = getMockEndpoint(toEmailNotificationVetCenterEndpoint);

        emailNotificationVetCenterMOCKEndpoint.expectedBodiesReceived(message);
        // Herausforderung ist, die Datei aus dem  Verzeichnis ablesen und camel Regeln zu prüfen
        template.sendBody(testFromEndpoint, message);

        emailNotificationVetCenterMOCKEndpoint.assertIsSatisfied();
    }
}

这是Principal和enum EPrincipal的片段:

public class Principal {
    private EPrincipal principal;

    public EPrincipal getPrincipal() {
        return principal;
    }
    public void setPrincipal(EPrincipal principal) {
        this.principal = principal;
    }
}

public enum EPrincipal {
    VETCENTER("Vetcenter"), OSTEOTHEK("Osteothek");
    private final String principal;

    EPrincipal(final String principal)
    {
        this.principal = principal;
    }

    public String principal()
    {
        return principal;
    }
}

我不知道如何为这个代码段进行模拟:

.when(PredicateBuilder.isEqualTo(constant(EPrincipal.VETCENTER.principal()), simple("${header.principal.principal.principal}")))

这部分更精确:

simple("${header.principal.principal.principal}")

这是表达语言,我没有idiea如何为它创建一个模拟。是否有其他解决方案为它创建单元测试?

非常感谢您的帮助

1 个答案:

答案 0 :(得分:0)

强制principalServiceMOCKgetPrincipal中返回您想要的测试主体。

看看下面的简化示例。

接口:

public static interface PrincipalService {
    Principal getPrincipal(String id);
    Principal getPrincipal();
}

测试类:

@Mock
PrincipalService principalServiceMOCK;

@EndpointInject(uri = "mock:result")
MockEndpoint resultEndpoint;

@Override
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    Principal principal = new Principal();
    principal.setPrincipal(Type.VETCENTER);
    Mockito.when(principalServiceMOCK.getPrincipal(TEST_ID)).thenReturn(principal);
    Mockito.when(principalServiceMOCK.getPrincipal()).thenReturn(principal);
    super.setUp();
}

@Test
public void test() throws InterruptedException {
    resultEndpoint.expectedMessageCount(1);
    resultEndpoint.expectedBodiesReceived(TEST_ID); // OK
    resultEndpoint.expectedHeaderReceived("principal1", Type.VETCENTER);
    resultEndpoint.expectedHeaderReceived("principal2", Type.VETCENTER);

    template.sendBody("direct:start", TEST_ID);

    resultEndpoint.assertIsSatisfied();
}

@Override
protected RouteBuilder createRouteBuilder() throws Exception {
    return new RouteBuilder() {
        @Override
        public void configure() {
            from("direct:start")
                    .setHeader("principal1").method(principalServiceMOCK, "getPrincipal(${body}).getPrincipal()")
                    .setHeader("principal2").method(principalServiceMOCK, "getPrincipal().getPrincipal()")
                    .to("mock:result");
        }
    };
}

请注意:

  • 如果使用原始服务实现和constant,那么在配置时评估标头(= configure()被调用)以及在运行时使用method(= direct:start被调用)。
  • 如果使用模拟服务,那么在两种情况下都会在配置时评估标头。