Am I missing something basic? @Alternatives @BeforeClass

252 views
Skip to first unread message

Paul Grillo

unread,
Jun 6, 2014, 4:15:01 PM6/6/14
to cdi-...@googlegroups.com
Downloaded and started using this.  It has real good potential.  But i'm seeing two basic things that seem to fail.
Has anybody experienced or tried this scenario?  We use @Specializes within our product, where needed.  Unit test doesn't appear to see them.  I can provide real code.  Sorry if this is not the place to post this type of question.  Just wondering if this has been seen.

@RunWith(CdiRunner.class)
public class Test
@Inject A  

public class A
@Inject Class B  /// here we get Class B, instead of Class C.  This works outside of Junit.
                         /// i tried injecting Class B in the base unit test, same problem.

@Specializes
class C extends Class B

=====================
@ActivatedAlternatives (Alt.class)  // :)  this works perfectly and allows me to mock classes when needed.

@Alternative
Class Alt extends B


Paul Grillo

unread,
Jun 6, 2014, 4:28:01 PM6/6/14
to cdi-...@googlegroups.com
I've attached 4 simple classes that show the problem, unless i misunderstand how it should work.

I pasted them inline below:

@RunWith(CdiRunner.class)
public class SpecializeTest {
  @Inject private Cars cars;
  @Inject private Car car;
  
  @Test
  public void testSpecial(){
    System.out.println("cars:"+String.valueOf(cars.getClass().getName()));
    System.out.println("car:"+String.valueOf(car.getClass().getName()));
  }
}

package cdiunit;

public class Cars {

}


public class Car {

}

@Specializes
public class Ford extends Car{

}
=============================
cdiunit.zip

Bryn Cooke

unread,
Jun 6, 2014, 4:28:17 PM6/6/14
to cdi-...@googlegroups.com
Hi,
I've not used @Specializes before, however the normal CDI rules will apply to classes as long as they are discovered by the runner. If class C cannot be transitively discovered by examining fields, parameters or return types then you need to use @AdditionalClasses to include the class in your deplyment.

@RunWith(CdiRunner.class)
@AdditionalClasses(C.class)
public class Test
@Inject A  

Let me know how it goes.

Bryn
--
You received this message because you are subscribed to the Google Groups "CDI-Unit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cdi-unit+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Paul Grillo

unread,
Jun 6, 2014, 4:31:36 PM6/6/14
to cdi-...@googlegroups.com
thank you Byrne.  I could add the class names using additional classes,  to see if it exists.   The problem is, i don't know, ahead of time, what classes may be specialized when testing.  They are part of the deployment and unknown to the test runner.

Normal runtime weld scans classes in the classpath and finds these specialized classes and then uses them when requested to inject.  At least that is how it works in production. 

Bryn Cooke

unread,
Jun 6, 2014, 4:41:13 PM6/6/14
to cdi-...@googlegroups.com
Hi
CDI-Unit does not include everything in the classpath for performance reasons. In large projects startup events can easily result in it taking minutes to run each test. Instead it transitively discovers classes starting with the test class. In your case it would find Cars and Car.

Your only other options are to:
  • use @AdditionalPackages or @AdditionalClasspaths if possible
  • start up the cdi container manually using Weld or through Deltaspike
  • use Arquillian
Bryn

Paul Grillo

unread,
Jun 6, 2014, 4:52:03 PM6/6/14
to cdi-...@googlegroups.com
sounds good, makes sense.  I'll see if i can pass some packages to the runner. If i intialize WeldContainer does CDI-Unit work with it?  Also, in particular, 
@AdditionalPackages
What is the syntax.  does it take wildcard?  my.package.*  ?  or do i have to have one for every package name.
Even here, i may not be aware of introduced packages, but they would be part of our domain.
example:
our.product   = our base domain
our.product.a or our.product.b  may be introduced (i won't know about a,b) - and there may be specialized classes in there.

Thanks so much for answering these questions.  Trying to go with something clean and simple like you've developed.  I'll move to something like arquillian if i rally have to ...

bryn

unread,
Jun 6, 2014, 4:58:27 PM6/6/14
to cdi-...@googlegroups.com
If you start the CDI container manually then you can't use CDI unit.

Additional packages takes an array of classes, it will pull in packages that those classes belong to, so this may not be any good for you.

Good luck.
Bryn

Paul Grillo

unread,
Jun 6, 2014, 5:17:39 PM6/6/14
to cdi-...@googlegroups.com
thanks much.  I think that i may have an answer.  Using additionalClassPath and changing some of our procedures should solve this problem.  Your solution is very clean.

Thanks again for your incredibly fast response.  Look forward to using this.
Reply all
Reply to author
Forward
0 new messages