Тестирование Apache Camel Route с транзакцией - PullRequest
0 голосов
/ 24 октября 2018

У меня верблюжий маршрут с transacted () с политикой.Во время моего теста JUnit я не хочу проверять поведение транзакции на маршруте.Я пытаюсь удалить его, используя:

weaveByType(TransactedDefinition.class).remove();

, но он выдает ошибку, говоря:

java.lang.IllegalArgumentException: There are no outputs which matches: TransactedDefinition in the route.

Можно ли как-нибудь удалить транзакцию из моего верблюжьего маршрута лучше?

1 Ответ

0 голосов
/ 28 октября 2018

Я предпочитаю макетирование TransactionManager и SpringTransactionPolicy в тесте JUnit вместо удаления поведения транзакции из маршрута.

Вы можете использовать для этого мой служебный класс:

import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.spring.spi.SpringTransactionPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.*;
import org.springframework.transaction.support.*;

import javax.naming.NamingException;
import javax.transaction.TransactionManager;
import java.lang.reflect.Field;

public class TransactionalMock {
    private static final Logger LOG = LoggerFactory.getLogger(TransactionalMock.class);

    public static void register(JndiRegistry registry) throws NamingException {
        AbstractPlatformTransactionManager transactionManager = new AbstractPlatformTransactionManager() {
            @Override
            protected Object doGetTransaction() throws TransactionException {
                return null;
            }
            @Override
            protected void doBegin(Object o, TransactionDefinition transactionDefinition) throws TransactionException {
                LOG.info("doBegin {}, {}", o, transactionDefinition);
            }
            @Override
            protected void doCommit(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException {
                LOG.info("doCommit {}", defaultTransactionStatus);
            }
            @Override
            protected void doRollback(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException {
                LOG.info("doRollback {}", defaultTransactionStatus);
            }
        };
        //transactionManager.setNestedTransactionAllowed(true);

        unbindType(registry, TransactionManager.class);
        replaceBean(registry, "transactionManager", transactionManager);

        for (Field propagation: TransactionDefinition.class.getFields()){
            if (propagation.getName().startsWith(DefaultTransactionDefinition.PREFIX_PROPAGATION)){
                SpringTransactionPolicy springTransactionPolicy = new SpringTransactionPolicy();
                springTransactionPolicy.setTransactionManager(transactionManager);
                springTransactionPolicy.setPropagationBehaviorName(propagation.getName());
                replaceBean(registry, propagation.getName(), springTransactionPolicy);
            }
        }
    }

    private static void replaceBean(JndiRegistry registry, String name, Object bean) throws NamingException {
        if (registry.lookupByName(name) != null){
            registry.getContext().unbind(name);
        }
        registry.bind(name, bean);
    }
    private static void unbindType(JndiRegistry registry, Class<?> type) throws NamingException {
        for (String name: registry.lookupByType(type).keySet()){
            registry.getContext().unbind(name);
        }
    }
}

Примериспользование регистра TransactionalMock #:

public class TransactionalMockTest extends CamelTestSupport {

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:transacted")
                        .transacted()
                        .to("mock:transacted");
                from("direct:required")
                        .transacted("PROPAGATION_REQUIRED")
                        .to("mock:required");
                from("direct:requiresNew")
                        .transacted("PROPAGATION_REQUIRES_NEW")
                        .to("mock:requiresNew");
                    }
        };
    }

    @Override
    protected JndiRegistry createRegistry() throws Exception {
        JndiRegistry registry = super.createRegistry();
        TransactionalMock.register(registry);
        return registry;
    }

    @Test
    public void testTransacted() throws Exception{
        MockEndpoint mockEndpoint = getMockEndpoint("mock:transacted");
        template.sendBody("direct:transacted","");
        mockEndpoint.setExpectedCount(1);
        mockEndpoint.assertIsSatisfied();
    }
    @Test
    public void testTransactedRequired() throws Exception{
        MockEndpoint mockEndpoint = getMockEndpoint("mock:required");
        template.sendBody("direct:required","");
        mockEndpoint.setExpectedCount(1);
        mockEndpoint.assertIsSatisfied();
    }
    @Test
    public void testTransactedRequiresNew() throws Exception{
        MockEndpoint mockEndpoint = getMockEndpoint("mock:requiresNew");
        template.sendBody("direct:requiresNew","");
        mockEndpoint.setExpectedCount(1);
        mockEndpoint.assertIsSatisfied();
    }
}
...