Announcement Announcement Module
Collapse
No announcement yet.
Spring Test Proxies Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Test Proxies

    Hi All,

    I've been using many different portions of Spring throughout my career, but the behavior I'm seeing in one of my Spring Tests is just driving me nuts.

    Let's say I have a Repository that I am trying to test:

    public class CommentsDAO implements ICommentsDAO {

    /**
    * The JPA Entity Manager
    */
    @PersistenceContext
    private EntityManager em;

    ...
    }

    with Spring Test file:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schem...g-jdbc-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schem...ing-tx-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- Annotation Driven Transactions -->
    <tx:annotation-driven/>

    <!-- JPA Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionM anager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityMana gerFactoryBean">
    <property name="persistenceUnitName" value="test"/>
    </bean>

    <bean id="commentsArchive" class="com.xxx.wall.dao.wall.CommentsDAO"/>
    </beans>

    and Spring/JUnit Test file:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {
    "classpath:spring/snocell-wall-orm-test.xml"
    })
    @TransactionConfiguration(transactionManager = "transactionManager")
    @Transactional
    public class ICommentsDAOTest {

    @Autowired
    private CommentsDAO archive;
    }

    I always get errors from Spring that there is no bean of type CommentsDAO. If I switch to the interface type, ICommentsDAO, then everything is happy. It seems that Spring is actually using a dynamic proxy for the bean here instead of just using the bean I have specified.

    Now I thought this may make sense because of the @Transactional I am using here. However, that doesn't work even when I remove all @Transactional and @TransactionConfiguration here.

    Can anyone explain why this is happening? How can I actually just reference the concrete type here instead of the interface type?

    Thanks!!

    Ronak Patel

  • #2
    Please use [ code][/code ] tags when posting code that way it remains readable.

    Spring creates proxies to do exception handling/exception translation, for that it needs a proxy.

    Comment


    • #3
      Hi Marten,

      So, is there any particular way I can test the methods for CommentsDAO (which are not already within the ICommentsDAO interface) and still use Spring Test? That doesn't seem like it can be done here.

      Ronak

      Comment


      • #4
        You should only use springs testing support if you want to do an integration test, if you want to do a unit test then you shouldn't use spring. Which is what you are trying to do at least from my pov. So simply create an instance, mock/stub the dependencies and off you go with your test.

        Or create a special context xml which only contains your class, no annotation-driven stuff and inject the dependencies yourself. But that seems to much work.

        Also we could debate about the fact that you want to test methods inside the CommentsDAO they should be covered by testing your public API. If they aren't then why are those methods there anyway. But that is more of religious debate .

        Comment


        • #5
          If they aren't then why are those methods there anyway.

          Comment


          • #6
            I wasn't aware that concrete objects that take in other dependencies via setters to do their job also require the setters/getters to be defined in the Interface.

            If so, that's news to my ears....

            Comment


            • #7
              Well another debate we can have do you need/want to test your getter/setters... But that is something you can quite easily do without spring isn't it... Simply do injection yourself and see if the same object comes out... There is no need to do that with spring, on the other hand if your setter isn't working the app should blow up when invoking business methods.

              Comment

              Working...
              X