[atunit commit] r27 - wiki

2 views
Skip to first unread message

codesite...@google.com

unread,
Nov 12, 2007, 11:16:13 PM11/12/07
to atunit...@googlegroups.com
Author: logan.johnson
Date: Mon Nov 12 20:15:55 2007
New Revision: 27

Added:
wiki/AtUnitTest.wiki
wiki/SupportedContainers.wiki
wiki/SupportedMockFrameworks.wiki
wiki/WhyAtUnit.wiki

Log:
initial drafts of some wiki docs

Added: wiki/AtUnitTest.wiki
==============================================================================
--- (empty file)
+++ wiki/AtUnitTest.wiki Mon Nov 12 20:15:55 2007
@@ -0,0 +1,63 @@
+#summary A quick guide to the pieces of an !AtUnit test
+
+=Anatomy of an !AtUnit test=
+
+!AtUnit is driven by annotations (hence the name). The example below
shows the !AtUnit annotations in context.
+
+The specifics of Guice and JMock integration will be covered
elsewhere. The general semantics of the !AtUnit annotations are the
same for all containers and mock object frameworks.
+
+{{{
+
+import atunit.*;
+import atunit.example.subjects.*;
+// ...
+import com.google.inject.Inject;
+import org.junit.runner.RunWith;
+
+@RunWith(AtUnit.class)
+@Container(Container.Option.GUICE)
+@MockFramework(MockFramework.Option.JMOCK)
+public class ExampleGuiceAndJMockTest {
+
+ @Inject @Unit GuiceUserManager manager;
+ @Inject User emptyUser;
+ Mockery mockery;
+ @Mock UserDao dao;
+ @Stub Logger ignoredLogger;
+
+ @Test
+ public void testGetUser() {
+ mockery.checking(new Expectations() {{
+ one (dao).load(with(equal(500)));
+ will(returnValue(emptyUser));
+ }});
+ assertSame(emptyUser, manager.getUser(500));
+ }
+}
+
+}}}
+
+==`@RunWith(AtUnit.class)`==
+This is a JUnit annotation-- it tells JUnit to use !AtUnit to run the
test. Most of !AtUnit's smarts live in its test runner, so this is
required for the other annotations to work.
+
+==`@Container` and `@ContainerClass`==
+These annotations tell !AtUnit which Inversion of Control container to
use. `@Container` is for specifying a supported container;
`@ContainerClass` takes a class name as a parameter so that you can
plug in your own container.
+
+The container is used to inject dependencies into your test's fields,
and into each other. Container-specific annotations are needed in
order to request injection of a field, except where noted in this document.
+
+See the special notes on [SupportedContainers supported containers]
for more details on using your container of choice.
+
+==`@MockFramework` and `@MockFrameworkClass`==
+These annotations are analagous to the container annotations above,
but for mock frameworks. Again, `@MockFramework` specifies supported
framework; `@MockFrameworkClass` allows you to plug in your own.
+
+For details on using a specific mock objects framework, see the page
on [SupportedMockFrameworks supported frameworks].
+
+==`@Unit`==
+A unit test should have one and only one subject, to keep your tests
clear and focused. An !AtUnit test _must_ have exactly one subject,
and it must be annotated with `@Unit`.
+
+==`@Mock` and `@Stub`==
+An !AtUnit test can obtain two kinds of mock object from the framework
of your choice:
+ * _Mocks_ have strict expectations and can be used to validate interactions.
+ * _Stubs_ are ignored by the framework and are used to supply
dependencies that are irrelevant to the test.
+
+!AtUnit examines fields that carry the `@Mock` and `@Stub` annotations
and uses the configured framework to create mock objects to fill those
fields. If you're using a container, these field values will be bound
appropriately within the container so that they can be injected by the
container into other objects. If you are not using a container, or if
these fields are not injected by the container, !AtUnit will inject the
fields itself. This means that in most cases, you need not bother with
container-specific annotations on `@Mock` or `@Stub` fields.

Added: wiki/SupportedContainers.wiki
==============================================================================
--- (empty file)
+++ wiki/SupportedContainers.wiki Mon Nov 12 20:15:55 2007
@@ -0,0 +1,72 @@
+#summary Details on using Guice and Spring.
+
+=Supported Containers=
+
+This document consists of container-specific notes. For general
information about using dependency injection containers with !AtUnit,
see the [AtUnitTest test anatomy page].
+
+==Guice==
+
+To use Guice for dependency injection, annotate your test class with `@Container(Container.Option.GUICE)`:
+
+{{{
+// ...
+
+@RunWith(AtUnit.class)
+@Container(Container.Option.GUICE)
+public class ExampleGuiceTest {
+
+ @Inject @Unit GuiceUser user;
+
+ // ...
+}
+}}}
+
+Any test that uses Guice will be instantiated using the Guice
`Injector`. If you are using a [SupportedMockFrameworks mock
framework], any mocks you declare will be bound to their interfaces as
singletons and injected into objects that request those interfaces.
+
+If a test requires more flexibility in your bindings than is provided
via field annotation-- for instance, if it requires the injection of
some configuration parameters into the test subject-- the test class
may optionally implement `Module`. Any bindings defined in the
`configure` method will be merged with the field bindings and used when
instantiating the test:
+
+{{{
+// ...
+
+@RunWith(AtUnit.class)
+@Container(Container.Option.GUICE)
+public class ExampleGuiceTest implements Module {
+
+ @Inject @Unit GuiceUser user;
+
+ public void configure(Binder b) {
+ b.bind(String.class).annotatedWith(Names.named("user.name")).toInstance("fred");
+ b.bind(Integer.class).annotatedWith(Names.named("user.id")).toInstance(500);
+ }
+
+ // ...
+}
+}}}
+
+==Spring==
+
+To use Spring for dependency injection, annotate your test with `@Container(Container.Option.SPRING)`:
+
+{{{
+package atunit.example;
+// ...
+
+@RunWith(AtUnit.class)
+@Container(Container.Option.SPRING)
+public class ExampleSpringTest {
+
+ @Bean @Unit User user;
+ @Bean("username") String username;
+
+ // ...
+}
+}}}
+
+By default, !AtUnit will look in the classpath for a Spring XML
context configuration file named after the test class and in the same
package. In the example above, !AtUnit will look in the classpath
`/atunit/example/ExampleSpringTest.xml`. No exception will be thrown
if the XML file is not found, because an XML file is often not needed.
+
+An alternate location for the XML file may be specified by annotating
the test class with `@Context("/path/to/filename.xml")`
+
+
+Fields annotated with `@Bean` will be populated from the application
context. By default, they are autowired by type. The `@Bean`
annotation also takes a bean name parameter-- if present, the named
bean will be used to populate the field.
+
+If the test uses a [SupportedMockFrameworks mock object framework],
and has any mock object fields declared, those fields will be populated
by !AtUnit if they are not populated by Spring. If they carry the
`@Bean` annotation, they will be placed into the Spring context for
injection into other objects (using autowiring by type by default). If
no bean name is specified in the annotation, one will be generated.
\ No newline at end of file

Added: wiki/SupportedMockFrameworks.wiki
==============================================================================
--- (empty file)
+++ wiki/SupportedMockFrameworks.wiki Mon Nov 12 20:15:55 2007
@@ -0,0 +1,52 @@
+#summary Details on using JMock and EasyMock
+
+=Supported Mock Object Frameworks=
+
+This document contains framework-specific notes. For general
information about using mock objects with !AtUnit, see the [AtUnitTest
test anatomy page].
+
+==!EasyMock==
+
+To use !EasyMock in your test, annotate your test class with *`@MockFramework(MockFramework.Option.EASYMOCK)`*:
+
+{{{
+// ...
+
+@RunWith(AtUnit.class)
+@MockFramework(MockFramework.Option.EASYMOCK) // tells AtUnit to use EasyMock
+public class ExampleEasyMockTest {
+
+ @Mock UserDao dao;
+ @Stub Logger log;
+
+ // ...
+}
+
+}}}
+
+When using !EasyMock, fields annotated with *`@Mock`* will be
populated with strict mocks, and fields annotated with *`@Stub`* will
be populated with nice mocks. See
[http://easymock.org/EasyMock2_3_Documentation.html the EasyMock
documentation] for an explanation of the difference.
+
+==JMock==
+
+To use JMock, annotate your test class with *`@MockFramework(MockFramework.Option.JMOCK)`*:
+
+{{{
+// ...
+
+@RunWith(AtUnit.class)
+@MockFramework(MockFramework.Option.JMOCK) // use JMock for mock objects
+public class ExampleJMockTest {
+
+ Mockery mockery;
+ @Mock UserDao dao;
+ @Stub Logger log;
+
+ // ...
+}
+}}}
+
+If you have a field of type *`Mockery`*, !AtUnit will populate it with
the same `Mockery` it uses to create your mocks and stubs.
+
+Fields annotated with *`@Mock`* are populated with normal JMock mock
objects. Since mocks are useless without the `Mockery`, if you have
`@Mock` fields you must also have a `Mockery` field or !AtUnit will
throw an exception.
+
+Fields annotated with *`@Stub`* are also populated with mock objects,
but the `Mockery` is instructed to ignore them. The presence of
`@Stub` fields does not require the presence of a `Mockery` field.
+

Added: wiki/WhyAtUnit.wiki
==============================================================================
--- (empty file)
+++ wiki/WhyAtUnit.wiki Mon Nov 12 20:15:55 2007
@@ -0,0 +1,7 @@
+#summary How !AtUnit helps test authors.
+
+=Why !AtUnit?=
+
+A key tenet of unit testing is isolation. You want to test one object
at a time, and often you want to test its interactions with other
objects. The Inversion of Control pattern facilitates isolation, and
mock objects help test interactions. Unfortunately, the use of IoC
containers and mock object frameworks can introduce a lot of tedious
boilerplate into your unit tests. Boilerplate is the enemy of clarity,
and tedium is demotivating; good developers love tests and hate
duplication. This is where !AtUnit can help.
+
+!AtUnit reduces to an absolute minimum the setup code for unit tests,
especially tests which use an IoC container and mock objects.
Typically, a couple of annotations on the test class (or a test
superclass) and some annotated fields are all that's required. You can
use the container and mock toolkit of your choice: Some popular
options are supported out of the box, and it's easy to plug in your
own. Neither the container nor the mock toolkit is required, though.
!AtUnit will help you write tests even without them.

Reply all
Reply to author
Forward
0 new messages