oghenez / mycila

Automatically exported from code.google.com/p/mycila
0 stars 0 forks source link

Guice2/TestNG: Injection only done once for each test class #14

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
The objects are injected only once for each test instance.
I think it should be possible (maybe the default) that before each test
method is initialized the test objects are reinitialized.

I personally do all my stuff in setup methods annotated with @BeforeMethod
and clean up with @AfterMethod annotated methods.

Original issue reported on code.google.com by johan...@familieschneider.info on 26 Sep 2009 at 1:19

GoogleCodeExporter commented 8 years ago
Hi,

I don't think it would be a good idea, for the simple reason that for TestNG and
Junit, the flow and lifecycle of test instance is different. 

- Junit's default behavior (but which could be changed by creating a Runner) is 
to
create a test instance *for each test method*. So the @BeforeTest is called on a
fresh new instance, and @BeforeClass is called before all instances are created,
that's why the method needs to be static.

- TestNG's behavior (which cannot be changed since this framework does not 
provide as
many hook possibilities as Junit), is to create *one test instance* (if not 
running
in parallel), and reuse them to call by reflexion each test method. So the
@BeforeTest is called on a reused instance, and @BeforeClass is called before 
all
test methods are run.

So as i understand, i suppose you are using TestNG ? If you are using TestNG, 
you are
aware that there is one instance for all test. You currently *patch* this by
reinitializing objects before each test. But remember that a test should be 
isolated.
To verify this, you should be able to run your tests in parallel, which is not
currently the case if you reinitialize objects before each test of the same 
loaded
instance. 

So if you use TestNG, I suggest you might refactor your test to be sure they are
isolated. You could see TestNG much more like this: a test is a class, a method 
is a
specific case of a test for which altering data does not impact other cases. An
example is this:

class DAOTest 
 - method test_find
 - method test_get
 - method test_get_throw_exception_if_not_exist
 - ...
 - method test_save (this method would have @Transactional + rollback forced to true
to not change database state when this test finished)

Cheers,

Mat'

Original comment by mathieu....@gmail.com on 26 Sep 2009 at 2:51

GoogleCodeExporter commented 8 years ago
Yes you are right. I am using TestNG. Should have mentioned that.

I don't think I "patch" the behaviour of TestNG. I understand this a normal
behaviour. One instance of a test class is created. Methods annotated with
@BeforeMethod/@AfterMethod are used to ensure that the objects is 
(re)initialized
properly.
Of course that doesn't allow parallel execution. But the alternative are many
different test classes or the JUnit behaviour which seems broken to me (every 
thing
has to be initialized for every method).

Isn't there any workaround? Can I trigger the (re)injection in my own 
@BeforeMethod
setup method?

Original comment by johan...@familieschneider.info on 28 Sep 2009 at 10:30

GoogleCodeExporter commented 8 years ago
Yes i think it would be possible, to recreate the entire Test Context and 
reinject.
For this, you can read about on the section "Custom integration" at
http://code.google.com/p/mycila/wiki/MycilaCustom. The goal would be to call 
again
the test preparation step: perhaps you can see how the AsbtractTestNG class is
developped. It should be something like this:

@BeforeClass(alwaysRun = true)
protected final void prepareTestInstance() {
    testNotifier = MycilaTesting.from(getClass()).configure(this).createNotifier(this);
    testNotifier.prepare();
}

Cheers,

Mat'

Original comment by mathieu....@gmail.com on 28 Sep 2009 at 1:37

GoogleCodeExporter commented 8 years ago
Note: MycilaTestNGTest source code is at
http://code.google.com/p/mycila/source/browse/mycila-testing/trunk/mycila-testin
g-api/src/main/java/com/mycila/testing/testng/MycilaTestNGTest.java.

If you need event firering, you will probably need to copy all this class and 
make
the TestNotifier object protected so that you can recreate it.

Original comment by mathieu....@gmail.com on 28 Sep 2009 at 1:41

GoogleCodeExporter commented 8 years ago

Original comment by mathieu....@gmail.com on 15 Nov 2009 at 11:10