You could also change from unit test to integration test in case a
component depends on other components, when you do that you can register
your mocks as a normal service and you don't have to make changes to your
code just to be able to test it.

Regards,
Bram

2014-09-16 17:35 GMT+02:00 Konstantine Kougios <[email protected]
>:

> Setter is ok, provided the bean is visible via an interface to other
> bundles. But it can create issues on bigger projects with lots of
> developers. I.e. A developer can use the setter to change the field on
> production code with disastrous results. Or even on test code that runs
> inside the container, which means subsequent tests that use the
> bean/service will fail because the service is in corrupted state. On the
> other hand, the forTesting(B b) is harmless as it returns a new instance
> and it’s method implies it should be used only for testing. Even if it is
> used in production code, it’s side effects will be limited to the code
> calling forTesting().
>
> Injecting via reflection can help avoid the setter & forTesting - after
> all those are only for test cases and not for production code and
> reflection will only be used for testing. I am not saying it’s the best
> approach, but I.e. Mockito can do that via @InjectMock and it looks pretty
> tidy way of doing that and production code remains clean of testing
> artifacts.
>
> http://docs.mockito.googlecode.com/hg/latest/org/mockito/InjectMocks.html
>
> Spring framework allows creation of non-mocked beans via separate
> application configuration xml files, which comes handy sometimes when we
> want to unit test using real objects.
>
> I suppose the best approach would be to use mockito, @InjectMocks when I
> want to test using mocks. And forTesting() can be used when we need to
> inject non-mock dependencies, for unit tests that prefer to use real
> objects.
>
>
> On 16/09/2014 16:13, "Neil Bartlett" <[email protected]> wrote:
>
> >Why not just create a setter method for this dependency and use that from
> >the unit test? I've never understood the desire to inject directly into
> >private fields.
> >
> >I also didn't understand your explanation about polluting state. What
> >does the state matter if this is a genuine unit test?
> >
> >Regards,
> >Neil
> >
> >--
> >Neil Bartlett
> >Sent from a phone
> >
> >
> >On Tuesday, 16 September 2014 at 15:31, Konstantine Kougios wrote:
> >
> >> I want to write a unit test which will run outside of the container. I
> >> want to mock dependencies. I don’t mind about lifecycle methods as my
> >> service won’t use them (or I don’t need / can mock them).
> >>
> >> Say for example I am writing A that uses B which downloads a big json
> >>file
> >> from the internet. I want to unit test it by mocking B so to avoid the
> >> download:
> >>
> >>
> >> @Service
> >> Class A {
> >> @Reference private B b;
> >>
> >> public void doSomething() {
> >> V v=b.download();
> >> …. use v
> >> }
> >>
> >> Public static A forTesting(B b){
> >> A a=new A();
> >> A.b=b;
> >> Return a;
> >> }
> >> }
> >>
> >> …. And then
> >>
> >> Public class Atest {
> >> @Test
> >> Public void testDoSomething() {
> >> B b=mock(B.class);
> >> When(b.download()).return(“file”);
> >> A a = A.forTesting(b);
> >> A.doSomething….
> >> }
> >> }
> >>
> >> Setters would be similar to the above but does felix/osgi provide a more
> >> transparent way (I.e. Via reflection)?
> >>
> >>
> >> On 16/09/2014 15:22, "David Jencks" <[email protected]>
> >>wrote:
> >>
> >> > You don't provide enough information to know what you are doing, and I
> >> > don't understand what you mean by a unit test.
> >> >
> >> > If you are writing a DS component and using Felix DS annotations, note
> >> > that the @Reference on a field without accessors results in byte code
> >> > generation of accessor methods. You might want to write them yourself.
> >> >
> >> > Is your "unit test" running in a DS container?
> >> >
> >> > If not, then you need to simulate the calls to the event
> >> > (bind/updated/unbind) and lifecycle (activate/modified/deactivate)
> >> > methods that the container will make in your unit test. After all the
> >> > "stop" methods (deactivate and unbind) are called, the container will
> >> > discard the component instance.
> >> >
> >> > If you are running in a DS container then register your B as a service
> >> > and the container will take care of calling the (generated, with your
> >> > current code)bind/unbiind methods.
> >> >
> >> > LIke every other component framework that accesses apparently
> >>invisible
> >> > members during runtime, DS calls setAccessible internally so it can
> >> > access them. The spec may support field injection in the future and it
> >> > will be supported using setAccssible pretty much exactly as David B.
> >> > suggests.
> >> >
> >> > david jencks
> >> >
> >> > On Sep 16, 2014, at 6:59 AM, Konstantine Kougios
> >> > <[email protected]> wrote:
> >> >
> >> > > Well, that¹s similar to the forTesting factory I mention but with
> >>the
> >> > > drawback that the state of A is corrupted until the JVM terminates.
> >>By
> >> > > corrupted I mean that my mock will be part of A until either the jvm
> >> > > stops
> >> > > or something else injects a different thing to A.b. If the mock is
> >>set
> >> > > this way while running in-container tests, A state is corrupted.
> >> > >
> >> > >
> >> > > On 16/09/2014 14:56, "David Bosschaert" <[email protected]
> >
> >> > > wrote:
> >> > >
> >> > > > Why not set the field b in your object manually to the mock B for
> >>unit
> >> > > > testing?
> >> > > >
> >> > > > Just assign it to the field. If you insist on having it private
> >>you
> >> > > > can call 'Field.setAccessible(true)' in your unit test and assign
> >>it
> >> > > > using reflection...
> >> > > >
> >> > > > Best regards,
> >> > > >
> >> > > > David
> >> > > >
> >> > > > On 16 September 2014 14:39, Konstantine Kougios
> >> > > > <[email protected]> wrote:
> >> > > > > Hi, say I got a service A, which has a
> >> > > > >
> >> > > > > @Reference private B b;
> >> > > > >
> >> > > > > Now I want to write a unit test and mock B, how can I inject the
> >> > > > > mocked
> >> > > > > dependency?
> >> > > > >
> >> > > > > Only reasonable thing I found so far is to have a static factory
> >> > > > > method
> >> > > > > on A, public static A forTesting(B b) { Š }
> >> > > > >
> >> > > > > Thanks,
> >> > > > >
> >> > > > > Kostas
> >> > > >
> >> > > >
> >>---------------------------------------------------------------------
> >> > > > To unsubscribe, e-mail: [email protected]
> >> > > > For additional commands, e-mail: [email protected]
> >> > > >
> >> > >
> >> > >
> >> > >
> >> > >
> >>---------------------------------------------------------------------
> >> > > To unsubscribe, e-mail: [email protected]
> >> > > For additional commands, e-mail: [email protected]
> >> > >
> >> >
> >> >
> >> >
> >> > ---------------------------------------------------------------------
> >> > To unsubscribe, e-mail: [email protected]
> >> > For additional commands, e-mail: [email protected]
> >> >
> >>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [email protected]
> >> For additional commands, e-mail: [email protected]
> >>
> >>
> >
> >
>
>

Reply via email to