[atunit commit] r14 - in trunk: . example/atunit/example lib/spring src/atunit src/atunit/jmock src/atunit/spring...

0 views
Skip to first unread message

codesite...@google.com

unread,
Nov 4, 2007, 1:07:40 AM11/4/07
to atunit...@googlegroups.com
Author: logan.johnson
Date: Sat Nov 3 23:07:01 2007
New Revision: 14

Added:
trunk/example/atunit/example/ExampleSpringEasyMockTest.java
trunk/example/atunit/example/ExampleSpringEasyMockTest.xml
trunk/example/atunit/example/ExampleSpringTest.java
trunk/example/atunit/example/ExampleSpringTest.xml
trunk/example/atunit/example/ExampleSpringWithContextLocationTest.java
trunk/example/atunit/example/ExampleSpringWithoutXmlTest.java
trunk/lib/spring/ (props changed)
trunk/lib/spring/commons-logging.jar (contents, props changed)
trunk/lib/spring/log4j-1.2.14.jar (contents, props changed)
trunk/lib/spring/spring-beans.jar (contents, props changed)
trunk/lib/spring/spring-context.jar (contents, props changed)
trunk/lib/spring/spring-core.jar (contents, props changed)
trunk/src/atunit/spring/
trunk/src/atunit/spring/Bean.java
trunk/src/atunit/spring/Context.java
trunk/src/atunit/spring/SpringContainer.java
trunk/test/atunit/spring/
trunk/test/atunit/spring/BrokenXmlContext.xml
trunk/test/atunit/spring/DefaultXmlContext.xml
trunk/test/atunit/spring/MergedContexts.xml
trunk/test/atunit/spring/SpringContainerTests.java
Modified:
trunk/.classpath
trunk/build.xml
trunk/src/atunit/AtUnit.java
trunk/src/atunit/Container.java
trunk/src/atunit/ContainerClass.java
trunk/src/atunit/MockFrameworkClass.java
trunk/src/atunit/jmock/JMockFramework.java

Log:
- Initial Spring support.
- Various bugs fixed, mostly annotation inheritance.
- Bumped version to 0.6

Modified: trunk/.classpath
==============================================================================
--- trunk/.classpath (original)
+++ trunk/.classpath Sat Nov 3 23:07:01 2007
@@ -12,6 +12,11 @@
<classpathentry kind="lib" path="lib/jmock/hamcrest-library.jar"/>
<classpathentry kind="lib" path="lib/jmock/jmock.jar"/>
<classpathentry kind="lib" path="lib/jmock/jmock-junit4.jar"/>
+ <classpathentry kind="lib" path="lib/spring/spring-beans.jar" sourcepath="lib/spring/spring-src.zip"/>
+ <classpathentry kind="lib" path="lib/spring/spring-context.jar" sourcepath="lib/spring/spring-src.zip"/>
+ <classpathentry kind="lib" path="lib/spring/spring-core.jar" sourcepath="lib/spring/spring-src.zip"/>
+ <classpathentry kind="lib" path="lib/spring/log4j-1.2.14.jar"/>
+ <classpathentry kind="lib" path="lib/spring/commons-logging.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>

Modified: trunk/build.xml
==============================================================================
--- trunk/build.xml (original)
+++ trunk/build.xml Sat Nov 3 23:07:01 2007
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="atunit" default="jar">

- <property name="version" value="0.5"/>
+ <property name="version" value="0.6"/>

<property name="build.dir" value="${basedir}/build"/>
<property name="src.dir" value="${basedir}/src"/>

Added: trunk/example/atunit/example/ExampleSpringEasyMockTest.java
==============================================================================
--- (empty file)
+++ trunk/example/atunit/example/ExampleSpringEasyMockTest.java Sat Nov
3 23:07:01 2007
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.example;
+
+import static org.junit.Assert.*;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import atunit.AtUnit;
+import atunit.Container;
+import atunit.Mock;
+import atunit.MockFramework;
+import atunit.Unit;
+import atunit.spring.Bean;
+
+/**
+ * Demonstrates use of Spring container in conjunction with a mock
framework, in this case EasyMock.
+ *
+ * @author Logan Johnson <logan....@gmail.com>
+ */
+
+@RunWith(AtUnit.class)
+@Container(Container.Option.SPRING)
+@MockFramework(MockFramework.Option.EASYMOCK)
+public class ExampleSpringEasyMockTest {
+
+ /**
+ * Beans are autowired by type, by default.
+ */
+ @Bean @Unit SimpleManager manager;
+
+ /**
+ * Mocks and Stubs that are also annotated with Bean will be placed
into the application context like
+ * any other bean. If a name is specified, it will be used. If no
name is specified, one will be generated.
+ * Mock or Stub Beans are candidates for autowiring by type.
+ *
+ * In other words: Declare a Mock or Stub field, annotate it with
Bean, and it's just like you've put it
+ * in the XML.
+ *
+ */
+ @Bean("daoBean") @Mock SimpleDao dao;
+
+
+ @Test
+ public void testMocksAndContext() {
+ assertNotNull(manager);
+ assertNotNull(dao);
+ assertSame(dao, manager.getDao());
+
+ EasyMock.expect(dao.loadString()).andReturn("loaded string");
+ EasyMock.replay(dao);
+
+ assertEquals("loaded string", manager.getString());
+
+ EasyMock.verify(dao);
+ }
+
+ public static class SimpleManager {
+ private SimpleDao dao;
+ public void setDao(SimpleDao dao) {
+ this.dao = dao;
+ }
+ public SimpleDao getDao() {
+ return dao;
+ }
+ public String getString() {
+ return dao.loadString();
+ }
+ }
+
+ public static interface SimpleDao {
+ public String loadString();
+ }
+
+}

Added: trunk/example/atunit/example/ExampleSpringEasyMockTest.xml
==============================================================================
--- (empty file)
+++ trunk/example/atunit/example/ExampleSpringEasyMockTest.xml Sat Nov
3 23:07:01 2007
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+
+ <bean id="mgr" class="atunit.example.ExampleSpringEasyMockTest$SimpleManager">
+ <property name="dao" ref="daoBean"/> <!-- daoBean is a Mock,
defined in the test class and imported here -->
+ </bean>
+
+</beans>
\ No newline at end of file

Added: trunk/example/atunit/example/ExampleSpringTest.java
==============================================================================
--- (empty file)
+++ trunk/example/atunit/example/ExampleSpringTest.java Sat Nov 3
23:07:01 2007
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.example;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import atunit.AtUnit;
+import atunit.Container;
+import atunit.Unit;
+import atunit.spring.Bean;
+
+/**
+ * Demonstrates automatic Spring configuration loading and injection
of beans
+ * from the application context.
+ *
+ * By default, AtUnit will look for a configuration file named after
the test
+ * class plus a ".xml" suffix, parallel to the test class in the
classpath. In
+ * this example, AtUnit looks in the classpath for
+ * atunit/spring/ExampleSpringTest.xml.
+ *
+ * @author Logan Johnson <logan....@gmail.com>
+ *
+ */
+@RunWith(AtUnit.class)
+@Container(Container.Option.SPRING)
+public class ExampleSpringTest {
+
+ /**
+ * Any fields annotated with Bean will be injected from the context.
By default, annotated fields are
+ * autowired by type.
+ */
+ @Bean @Unit StringHolder holder;
+
+ /**
+ * If autowiring by type is not sufficient, you can specify the name
of the bean to inject.
+ */
+ @Bean("myString") String myString;
+
+ @Test
+ public void testInjectionFromContext() {
+ assertEquals("string loaded from context", myString);
+ assertSame(myString, holder.getString());
+ }
+
+ public static class StringHolder {
+ private String string;
+ public void setString(String string) {
+ this.string = string;
+ }
+ public String getString() {
+ return string;
+ }
+ }
+}

Added: trunk/example/atunit/example/ExampleSpringTest.xml
==============================================================================
--- (empty file)
+++ trunk/example/atunit/example/ExampleSpringTest.xml Sat Nov 3
23:07:01 2007
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+
+ <bean id="myString" class="java.lang.String">
+ <constructor-arg value="string loaded from context"/>
+ </bean>
+
+ <bean id="myStringHolder" class="atunit.example.ExampleSpringTest$StringHolder">
+ <property name="string" ref="myString"/>
+ </bean>
+
+</beans>
\ No newline at end of file

Added: trunk/example/atunit/example/ExampleSpringWithContextLocationTest.java
==============================================================================
--- (empty file)
+++
trunk/example/atunit/example/ExampleSpringWithContextLocationTest.java
Sat Nov 3 23:07:01 2007
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.example;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import atunit.AtUnit;
+import atunit.Container;
+import atunit.Unit;
+import atunit.example.ExampleSpringTest.StringHolder;
+import atunit.spring.Bean;
+import atunit.spring.Context;
+
+/**
+ * If you want to manually specify the location of a Spring
configuration file to use,
+ * you can do so with the Context annotation on your test class. This
test is exactly
+ * the same as {@link ExampleSpringTest}, except for the Context annotation.
+ *
+ * Normally AtUnit would look for
ExampleSpringWithContextLocationTest.xml, but I've told
+ * it to use ExampleSpringTest.xml instead.
+ *
+ * @author Logan Johnson <logan....@gmail.com>
+ *
+ */
+@RunWith(AtUnit.class)
+@Container(Container.Option.SPRING)
+@Context("ExampleSpringTest.xml")
+public class ExampleSpringWithContextLocationTest {
+
+ @Bean @Unit StringHolder holder;
+ @Bean("myString") String myString;
+
+ @Test
+ public void testInjectionFromContext() {
+ assertEquals("string loaded from context", myString);
+ assertSame(myString, holder.getString());
+ }
+
+}

Added: trunk/example/atunit/example/ExampleSpringWithoutXmlTest.java
==============================================================================
--- (empty file)
+++ trunk/example/atunit/example/ExampleSpringWithoutXmlTest.java Sat
Nov 3 23:07:01 2007
@@ -0,0 +1,97 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.example;
+
+import static org.junit.Assert.*;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import atunit.AtUnit;
+import atunit.Container;
+import atunit.Mock;
+import atunit.MockFramework;
+import atunit.Unit;
+import atunit.spring.Bean;
+
+/**
+ * Because fields annotated with Bean are taken from the Spring
context, and fields annotated with Bean and
+ * Mock/Stub are placed into the Spring context, and all beans are
autowired by type by default, you very
+ * frequently do not need a Spring XML file at all. Simply define the
Bean fields necessary to sufficiently
+ * wire your test, and AtUnit will do the rest.
+ *
+ * This test is exactly the same as {@link ExampleSpringEasyMockTest},
with one exception: there is no Spring
+ * configuration file.
+ *
+ * @author Logan Johnson <logan....@gmail.com>
+ *
+ */
+@RunWith(AtUnit.class)
+@Container(Container.Option.SPRING)
+@MockFramework(MockFramework.Option.EASYMOCK)
+public class ExampleSpringWithoutXmlTest {
+
+ /**
+ * Beans are autowired by type, by default.
+ */
+ @Bean @Unit SimpleManager manager;
+
+ /**
+ * Mocks and Stubs that are also annotated with Bean will be placed
into the application context like
+ * any other bean. If a name is specified, it will be used. If no
name is specified, one will be generated.
+ * Mock or Stub Beans are candidates for autowiring by type.
+ *
+ * In other words: Declare a Mock or Stub field, annotate it with
Bean, and it's just like you've put it
+ * in the XML.
+ *
+ */
+ @Bean("daoBean") @Mock SimpleDao dao;
+
+
+ @Test
+ public void testMocksAndContext() {
+ assertNotNull(manager);
+ assertNotNull(dao);
+ assertSame(dao, manager.getDao());
+
+ EasyMock.expect(dao.loadString()).andReturn("loaded string");
+ EasyMock.replay(dao);
+
+ assertEquals("loaded string", manager.getString());
+
+ EasyMock.verify(dao);
+ }
+
+ public static class SimpleManager {
+ private SimpleDao dao;
+ public void setDao(SimpleDao dao) {
+ this.dao = dao;
+ }
+ public SimpleDao getDao() {
+ return dao;
+ }
+ public String getString() {
+ return dao.loadString();
+ }
+ }
+
+ public static interface SimpleDao {
+ public String loadString();
+ }
+
+}

Added: trunk/lib/spring/commons-logging.jar
==============================================================================
Binary file. No diff available.

Added: trunk/lib/spring/log4j-1.2.14.jar
==============================================================================
Binary file. No diff available.

Added: trunk/lib/spring/spring-beans.jar
==============================================================================
Binary file. No diff available.

Added: trunk/lib/spring/spring-context.jar
==============================================================================
Binary file. No diff available.

Added: trunk/lib/spring/spring-core.jar
==============================================================================
Binary file. No diff available.

Modified: trunk/src/atunit/AtUnit.java
==============================================================================
--- trunk/src/atunit/AtUnit.java (original)
+++ trunk/src/atunit/AtUnit.java Sat Nov 3 23:07:01 2007
@@ -32,6 +32,7 @@
import atunit.easymock.EasyMockFramework;
import atunit.guice.GuiceContainer;
import atunit.jmock.JMockFramework;
+import atunit.spring.SpringContainer;

public class AtUnit extends JUnit4ClassRunner {

@@ -92,7 +93,8 @@

if ( containerAnno != null ) {
switch ( containerAnno.value() ) {
- case GUICE: containerClass = GuiceContainer.class;
+ case GUICE: containerClass = GuiceContainer.class; break;
+ case SPRING: containerClass = SpringContainer.class; break;
}
}

Modified: trunk/src/atunit/Container.java
==============================================================================
--- trunk/src/atunit/Container.java (original)
+++ trunk/src/atunit/Container.java Sat Nov 3 23:07:01 2007
@@ -28,7 +28,8 @@
public @interface Container {

public enum Option {
- GUICE
+ GUICE,
+ SPRING
}

Option value();

Modified: trunk/src/atunit/ContainerClass.java
==============================================================================
--- trunk/src/atunit/ContainerClass.java (original)
+++ trunk/src/atunit/ContainerClass.java Sat Nov 3 23:07:01 2007
@@ -17,6 +17,7 @@
package atunit;

import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -25,6 +26,7 @@

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
+@Inherited
public @interface ContainerClass {

Class<? extends Container> value();

Modified: trunk/src/atunit/MockFrameworkClass.java
==============================================================================
--- trunk/src/atunit/MockFrameworkClass.java (original)
+++ trunk/src/atunit/MockFrameworkClass.java Sat Nov 3 23:07:01 2007
@@ -17,6 +17,7 @@
package atunit;

import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -25,6 +26,7 @@

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
+@Inherited
public @interface MockFrameworkClass {

Class<? extends MockFramework> value();

Modified: trunk/src/atunit/jmock/JMockFramework.java
==============================================================================
--- trunk/src/atunit/jmock/JMockFramework.java (original)
+++ trunk/src/atunit/jmock/JMockFramework.java Sat Nov 3 23:07:01 2007
@@ -60,6 +60,7 @@
boolean isStub = (field.getAnnotation(Stub.class) != null);
if ( !isMock && !isStub ) continue;
if ( isMock && (mockery == null) ) throw new NoMockeryException();
+ if ( isStub && (mockery == null) ) mockery = new JUnit4Mockery();

Class<?> fieldType = field.getType();
if ( fieldType.isArray() ) {

Added: trunk/src/atunit/spring/Bean.java
==============================================================================
--- (empty file)
+++ trunk/src/atunit/spring/Bean.java Sat Nov 3 23:07:01 2007
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.spring;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Bean {
+
+ String value() default "";
+}

Added: trunk/src/atunit/spring/Context.java
==============================================================================
--- (empty file)
+++ trunk/src/atunit/spring/Context.java Sat Nov 3 23:07:01 2007
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.spring;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Inherited
+public @interface Context {
+
+ String value();
+
+}

Added: trunk/src/atunit/spring/SpringContainer.java
==============================================================================
--- (empty file)
+++ trunk/src/atunit/spring/SpringContainer.java Sat Nov 3 23:07:01 2007
@@ -0,0 +1,166 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.spring;
+
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.Map;
+
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContextException;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.UrlResource;
+
+import atunit.core.Container;
+
+public class SpringContainer implements Container {
+
+ @Override
+ public Object createTest(Class<?> testClass, Map<Field, Object>
fieldValues) throws Exception {
+
+ GenericApplicationContext ctx = new GenericApplicationContext();
+
+ for ( Field field : fieldValues.keySet() ) {
+
+ Bean beanAnno = field.getAnnotation(Bean.class);
+ if ( beanAnno == null ) continue;
+
+ AbstractBeanDefinition beandef =
defineInstanceHolderFactoryBean(field.getType(), fieldValues.get(field));
+
+ if (!beanAnno.value().equals("")) {
+ ctx.registerBeanDefinition(beanAnno.value(), beandef);
+ } else {
+ BeanDefinitionReaderUtils.registerWithGeneratedName(beandef, ctx);
+ }
+ }
+
+ loadBeanDefinitions(testClass, ctx);
+
+ fillInMissingFieldBeans(testClass, ctx);
+
+
+ ctx.refresh();
+
+ Object test = testClass.newInstance();
+ for ( Field field : testClass.getDeclaredFields() ) {
+ field.setAccessible(true);
+ Bean beanAnno = field.getAnnotation(Bean.class);
+ if ( beanAnno == null ) {
+ if ( fieldValues.containsKey(field) ) {
+ field.set(test, fieldValues.get(field));
+ }
+ } else {
+ if ( ! beanAnno.value().equals("") ) {
+ field.set(test, ctx.getBean(beanAnno.value()));
+ } else {
+ String[] beanNames = ctx.getBeanNamesForType(field.getType());
+ if ( beanNames.length < 1 ) {
+ throw new BeanCreationException("There are no beans defined with
type " + field.getType());
+ }
+ if ( beanNames.length > 1 ) {
+ throw new BeanCreationException("There are " + beanNames.length
+ " beans defined with type " + field.getType()
+ + "; consider wiring by name instead");
+ }
+ field.set(test, ctx.getBean(beanNames[0]));
+ }
+ }
+ }
+
+ return test;
+ }
+
+ protected void loadBeanDefinitions(Class<?> testClass,
BeanDefinitionRegistry registry) {
+ XmlBeanDefinitionReader xml = new XmlBeanDefinitionReader(registry);
+
+ String resourceName = testClass.getSimpleName() + ".xml";
+ Context ctxAnno = testClass.getAnnotation(Context.class);
+ if ( ctxAnno != null ) {
+ resourceName = ctxAnno.value();
+ }
+ URL xmlUrl = testClass.getResource(resourceName);
+ if ( xmlUrl != null ) {
+ xml.loadBeanDefinitions(new UrlResource(xmlUrl));
+ } else if ( ctxAnno != null) {
+ // is this the appropriate exception here?
+ throw new ApplicationContextException("Could not find context file
named " + resourceName);
+ }
+ }
+
+ protected void fillInMissingFieldBeans(Class<?> testClass,
GenericApplicationContext ctx) throws Exception {
+ for ( Field field : testClass.getDeclaredFields() ) {
+ Bean beanAnno = field.getAnnotation(Bean.class);
+ if ( beanAnno == null ) continue;
+ String name = beanAnno.value();
+ if ( !name.equals("") && !ctx.containsBean(name) ) {
+ ctx.registerBeanDefinition(name, defineAutowireBean(field.getType()));
+ } else if ( ctx.getBeansOfType(field.getType()).isEmpty() ) {
+
BeanDefinitionReaderUtils.registerWithGeneratedName(defineAutowireBean(field.getType()), ctx);
+ }
+ }
+ }
+
+ protected AbstractBeanDefinition defineAutowireBean(Class<?> type)
throws Exception {
+ AbstractBeanDefinition beandef =
BeanDefinitionReaderUtils.createBeanDefinition(null, type.getName(), type.getClassLoader());
+ beandef.setAutowireCandidate(true);
+ beandef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT);
+ return beandef;
+ }
+
+ protected AbstractBeanDefinition
defineInstanceHolderFactoryBean(Class<?> type, Object instance) throws
Exception {
+ ConstructorArgumentValues args = new ConstructorArgumentValues();
+ args.addIndexedArgumentValue(0, type);
+ args.addIndexedArgumentValue(1, instance);
+
+ AbstractBeanDefinition beandef =
BeanDefinitionReaderUtils.createBeanDefinition(null,
InstanceHolderFactoryBean.class.getName(), getClass().getClassLoader());
+ beandef.setConstructorArgumentValues(args);
+ beandef.setAutowireCandidate(true);
+ return beandef;
+ }
+
+ public static class InstanceHolderFactoryBean implements FactoryBean {
+
+ final Class<?> type;
+ final Object instance;
+
+ public InstanceHolderFactoryBean(Class<?> type, Object instance) {
+ this.type = type;
+ this.instance = instance;
+ }
+
+ @Override
+ public Object getObject() throws Exception {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getObjectType() {
+ return type;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+
+ }
+}

Added: trunk/test/atunit/spring/BrokenXmlContext.xml
==============================================================================
--- (empty file)
+++ trunk/test/atunit/spring/BrokenXmlContext.xml Sat Nov 3 23:07:01 2007
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+
+ <bean id="unit" class="java.lang.String">
+ <constructor-arg value="unit from context">
+ </bean>
+
+</beans>
\ No newline at end of file

Added: trunk/test/atunit/spring/DefaultXmlContext.xml
==============================================================================
--- (empty file)
+++ trunk/test/atunit/spring/DefaultXmlContext.xml Sat Nov 3 23:07:01 2007
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+
+ <bean id="unit" class="java.lang.String">
+ <constructor-arg value="unit from context"/>
+ </bean>
+
+</beans>
\ No newline at end of file

Added: trunk/test/atunit/spring/MergedContexts.xml
==============================================================================
--- (empty file)
+++ trunk/test/atunit/spring/MergedContexts.xml Sat Nov 3 23:07:01 2007
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+ <bean id="myholder"
class="atunit.spring.SpringContainerTests$StringListHolder" autowire="byType"/>
+
+</beans>
\ No newline at end of file

Added: trunk/test/atunit/spring/SpringContainerTests.java
==============================================================================
--- (empty file)
+++ trunk/test/atunit/spring/SpringContainerTests.java Sat Nov 3
23:07:01 2007
@@ -0,0 +1,229 @@
+/**
+ * Copyright (C) 2007 Logan Johnson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package atunit.spring;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+import java.util.Set;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+
+import atunit.AtUnit;
+import atunit.ContainerClass;
+import atunit.Mock;
+import atunit.MockFramework;
+import atunit.Stub;
+import atunit.Unit;
+
+public class SpringContainerTests {
+
+ JUnitCore junit;
+
+ @Before
+ public void setUp() {
+ junit = new JUnitCore();
+ }
+
+ @Test
+ public void tNoBeans() {
+ Result result = junit.run(TestClasses.NoBeans.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(1, result.getRunCount());
+ }
+
+ @Test
+ public void tUndefinedBeanFilledIn() {
+ Result result = junit.run(TestClasses.UndefinedBeanFilledIn.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void tMockIntegration() {
+ Result result = junit.run(TestClasses.MockIntegration.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void tNameBindings() {
+ Result result = junit.run(TestClasses.MockIntegration.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void tXmlContext() {
+ Result result = junit.run(TestClasses.DefaultXmlContext.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void tMergedContexts() {
+ Result result = junit.run(TestClasses.MergedContexts.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void tBrokenXmlContext() {
+ Result result = junit.run(TestClasses.BrokenXmlContext.class);
+ assertEquals(1, result.getRunCount());
+ assertFalse(result.wasSuccessful());
+ assertNotNull(result.getFailures().get(0).getException());
+ }
+
+ @Test
+ public void tSpecifiedContext() {
+ Result result = junit.run(TestClasses.SpecifiedXmlContext.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void tSpecifiedBadXmlContext() {
+ Result result = junit.run(TestClasses.SpecifiedBadXmlContext.class);
+ assertEquals(1, result.getRunCount());
+ assertFalse(result.wasSuccessful());
+ assertNotNull(result.getFailures().get(0).getException());
+ }
+
+
+
+ protected static class TestClasses {
+
+ @RunWith(AtUnit.class)
+ @ContainerClass(SpringContainer.class)
+ public static abstract class SpringTest {
+
+ }
+
+ public static class NoBeans extends SpringTest {
+ @Unit String unit;
+ @Test
+ public void tPass() {
+ assertTrue(true);
+ }
+ }
+
+ public static class UndefinedBeanFilledIn extends SpringTest {
+ @Bean @Unit String unit;
+ @Test
+ public void tPass() {
+ assertTrue(true);
+ }
+ }
+
+ @MockFramework(MockFramework.Option.EASYMOCK)
+ public static class MockIntegration extends SpringTest {
+ @Unit String unit;
+ @Bean @Stub List<String> stringList;
+ @Bean @Mock Set<String> stringSet;
+
+ @Test
+ public void tPass() {
+ assertNotNull(stringList);
+ assertNotNull(stringSet);
+ EasyMock.expect(stringSet.contains("mystring")).andReturn(true);
+ EasyMock.replay(stringSet);
+ assertTrue(stringSet.contains("mystring"));
+ }
+ }
+
+ @MockFramework(MockFramework.Option.EASYMOCK)
+ public static class BindByName extends SpringTest {
+ @Unit String unit;
+ @Bean("stringList") @Stub List<String> stringList;
+ @Bean("stringList2") @Stub List<String> stringList2;
+
+ @Test
+ public void tPass() {
+ assertNotNull(stringList);
+ assertNotNull(stringList2);
+ assertNotSame(stringList, stringList2);
+ }
+ }
+
+ public static class DefaultXmlContext extends SpringTest {
+ @Unit @Bean String unit;
+
+ @Test
+ public void tPass() {
+ assertEquals("unit from context", unit);
+ }
+ }
+
+ @Context("DefaultXmlContext.xml")
+ public static class SpecifiedXmlContext extends SpringTest {
+ @Unit @Bean String unit;
+
+ @Test
+ public void tPass() {
+ assertEquals("unit from context", unit);
+ }
+ }
+
+ @Context("ThisContextDoesNotExist")
+ public static class SpecifiedBadXmlContext extends SpringTest {
+ @Unit String unit;
+
+ @Test
+ public void tPass() {
+ assertTrue(true);
+ }
+ }
+
+ @MockFramework(MockFramework.Option.JMOCK)
+ public static class MergedContexts extends SpringTest {
+ @Bean @Stub List<String> list;
+ @Bean @Unit StringListHolder holder;
+
+ @Test
+ public void tMergedContexts() {
+ assertNotNull(list);
+ assertNotNull(holder);
+ assertSame(list, holder.list);
+ }
+ }
+
+ public static class BrokenXmlContext extends SpringTest {
+
+ @Bean @Unit String unit;
+
+ @Test
+ public void tXmlContext() {
+ assertNotNull(unit);
+ }
+ }
+ }
+
+ public static class StringListHolder {
+
+ protected List<String> list;
+
+ public void setList(List<String> list) {
+ this.list = list;
+ }
+ }
+}

Reply all
Reply to author
Forward
0 new messages