When com.day.cq.wcm.api.designer.Style injected in a Model, the adaptTo returns null

Description

When I inject AEM object Style like this in my Model.

I got `java.lang.NullPointerException` that the sling model instance where adaptTo returned is null.

Do we have any solution to mock the Style or fix it inside AemContext ?

Activity

Show:
Zeng Eric
March 18, 2016, 2:42 AM

Thanks a lot @Stefan.

I think this is what I needed, I'm happy to close this issue.

Stefan Seifert
March 15, 2016, 5:14 PM

i assume this will work only if you use @Inject instead of @AemObject annotation - because @Inject queries all possible injection sources, and one of these is "request attributes". if you use @AemObject this should not work, there is no caching of current style in a request attributes of that i'm aware (but i may be wrong here).

Zeng Eric
March 14, 2016, 4:51 AM

Thanks @Stefen.

Your solution works well!

But I find another way by chance, let me know if it's a hack or working way:
Before I adapt to the Model, I add attributes to the resource or request.

Stefan Seifert
March 11, 2016, 1:21 PM

the problem is not the @AemObject inject, the problem is the lack of support for Design and Style in AEM mocks
i started playing around implementing full support for Designer, Design and Style objects in AEM mocks in this branch, but this is quite complicated for a full implementation and still complicated to be used in unit tests.

so i've another proposal: you can register your own adapter factory on-the-fly. i've not tested it, but basically it should work like this:

  1. create a mock instance of com.day.cq.wcm.api.designer.Designer e.g. with Mockito

  2. define behavior of this Designer mock for designer.getDesign(<Page>) and return a mocked com.day.cq.wcm.api.designer.Design object

  3. define behavior of this Design mock for design.getStyle(<Cell>) and return a mocked com.day.cq.wcm.api.designer.Style

  4. register the mocked Designer instance in your unit test adadaption from ResourceResolver like this:

in this case your model should get the mocked style object injected instead of null. this code bypassed the MockDesigner implementation includes in AEM mocks (which does not provide any design or style instances) and uses your mock instead.
i came up with this proposal by looking at the source of AemObjectInjector and making sure all methods used by it are covered by the mock provided by Mockito.

Zeng Eric
March 4, 2016, 2:31 AM
Edited

Thanks @Stefan, I have tried to mock the whole Style object.
But it only works when I use `@Inject Style currentStyle`, if I use `@AemObject Style currentStyle`, the `myModel` instance becomes null, with no useful error message. Even if I put an `@Optional` to it.

So my real question is, how can I use @AemObject along with AemContext as unit test.

Done

Assignee

Unassigned

Reporter

Zeng Eric

Labels

None

Components

Priority

Major