How to mock a CQ5 Page object containing a cq5 tag - junit

I have a method on which I'd like to run a JUnit test. I'm mocking the cq5 page using JMockit.
My test method looks like this
#Mocked
Page page;
#Mocked
PageManager pageManager;
Tag testTag = pageManager.createTag("someID","someTitle","someDescription");//i've left out the try catch for brevety
System.out.println(testTag.getTitle()); // always null here
public void testSomeMethod() {
new Expectations() {
// variables declared here are mocked by default
{
page.getProperties();
propertyMap.put("cq:tags", testTag);
returns(new ValueMapDecorator(propertyMap));
}
};
String propertyValue = methodToBeTested(page);
Assert.assertEquals(propertyValue, "someTitle");
}
And the actual method to be tested does this :-
public static String getTopic(Page page) {
String topic = null;
Tag[] tags = page.getTags();
System.out.println(tags.size()); // returns 0 when I run the test.
for (int i = 0; i < tags.length; i++) {
Tag tag = tags[i];
topic = tag.getTitle();
}
}
return topic;
}
This always returns null when I run the test; however the method to be tested works correctly in the real scenario.
I suspect I'm not setting/mocking PageManager correctly, and consequently, my testTag is null
How do I mock this correctly to get the output I'm looking for?

You're getting to this testing from the wrong side. The way mocks (usually - I've never worked with jmockit specifically) work is, you create a blank object that acts as an impostor. This impostor is not a true PageManager - it only acts as one, and introduces himself as one whenever asked. When someone asks that impostor to do something (like calling it's method), the impostor does not know what to do, so it does nothing and returns null. However, you can tell the impostor how to behave in certain situations. Namely, you can tell it what to do when a method is called.
In your case, you don't need to create actual tags to test that method - you only need to mock a page object that, when asked for it's tags, will return an array containing a mocked tag which, in turn, when asked for it's title, will respond with the title you actually want to use in your test.
I don't know jmockit, so I cannot provide any code snippet. This, however, is a general question not strictly connected to CQ5/AEM

You may not be able to find any 'setter' methods for all objects you are trying to mock and this is anyways not the correct approach to mock.
The best way as mentioned by is to use mocked pages. You can use the Expectations class (mockit.Expectations) to mock the values to be returned by certain methods in the object.
See this example of mocking a 'SlingHttpServletRequest' object in a MockedClass class.
#Test
public void testMethod(#Mocked final SlingHttpServletRequest request){
String indicator ;
new Expectations() {
{
request.getParameter("archive");
returns("true");
}
};
indicator = OriginalClass.originalMethod(request);
Assert.assertEquals(indicator, "true");
}
In a similar way, you can mock other objects and their desired values.

I have answered the same question here: https://forums.adobe.com/thread/2536290
I ran into the same issue. in order to resolve Tags, they must exists under /content/cq:tags/your/tag or /etc/tags (legacy).
The Page#getTags implementation makes a call to TagManager#getTags which in turn tries to resolve the actual tag resource in the repo. Since you are testing in an AEM context, you have to load these tags in the appropriate location for the MockTagManager to resolve them.
What this means is that you need to load your tags into the AEM test context just like you've loaded your resources (via json).
Take a look at the aem-mock TagManager impl here: wcm-io-testing/MockTagManager.java at develop · wcm-io/wcm-io-testing · GitHub start with the resolve method and debug your way to figure out where you need to add those tags.

Related

Add components based on string variables in Blazor

We're creating a dynamic page of components in Blazor. The intention is to have dynamic applets displayed on a page. The idea is that we have a list of strings which correspond to Component names. We read through the string list and for each one, instantiate a blazor component or render fragment. These are just simple components, no passed in parameters or the like. ie:
string[] componentsStrings = {"Component1", "Component2"};
Expected output:
<Component1 />
<Component2 />
We can't come up with a way to do this. It seems like a fairly standard thing to do, but perhaps not? Does anyone know if this is even possible?
You will have to programmatically create a component which adds your custom components on the page using RenderTreeBuilder.
Chris Sainty has a blog post on this which you can read here: https://chrissainty.com/building-components-via-rendertreebuilder/
Basically there is an override for BuildRenderTree in the ComponentBase class which can be used:
public class Menu : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
builder.OpenElement(0, "nav");
builder.AddAttribute(1, "class", "menu");
}
}
Here is another tutorial.
Some tips from here:
Place base.BuildRenderTree(builder); at the start of the
BuildRenderTree method , not at the end.
Always start with the value 0 for the sequence parameter.

Assign super to variable in AS3

I have this:
public class Base {
public function whoAmI() {
trace("base");
}
}
public class Extended extends Base {
public function Extended() {
this.whoAmI() //prints extended
super.whoAmI() //prints base
var test = super;
test.whoAmI() //prints extended
}
public override function whoAmI() {
trace("extended");
}
}
The problem is when I do var test = super, it seems like this is assigned to test instead of super.
Is it possible to do the assignment so that test.whoAmI() prints "base"?
Edit: In the comments it is being said that using super in the way I propose would break overriding. I don't think that's the case. The way I am thinking of it, super could be used the same way as this. I understand that is not the way super is implemented, but using it that way would not break overriding as people are claiming. So for example the same way this is possible:
var test = this;
test.whoAmI();
This should be possible:
var test = super;
super.whoAmI();
It is obviously the choice of the language implementer to not do things this way, and I don't understand the reason why. It doesn't break things, but I guess it does make them more complicated.
I am not suggesting type-casting this to the super class. Obviously that wouldn't work.
You are thinking of "this" and "super" as 2 different instances, 2 different things but they in fact point to the same object (obviously) so at the end it's always "this". Using super is just a special keyword that allows the instance to point to the overrided definitions up the inheritance chain, it does not point to a different object. So "super" does correctly its job, it points to the instance and allow you each time you use it to access overrided definitions and that's it. There's of course no point on trying to store that keyword in a variable since in that case it just return correctly the instance it points to which is always "this".
It's simply a case of misunderstood inheritance principle and I've seen it before, super is mistaken for some kind of instance wrapper up the inheriatnce chain around the object "this" while it's in fact and always the same object.
No, this is not possible.
If this were possible, then overriding methods wouldn't be possible!
For example, take this function...
public function test(a:Object):void {
trace(a.toString());
}
You'd only get [object Object] back if your idea was how things worked.
Ok I understand what you mean your question is more about language definition and specification.
Look at this exemple in c# that explain how you can manage more precisely overriding in c# :
http://www.dotnet-tricks.com/Tutorial/csharp/U33Y020413-Understanding-virtual,-override-and-new-keyword-in-C
But
let's explain a litlle how it's work.
when you extend a class, it's like if you create an object composed of all the object in the inheritance tree so if B extends A and C extends B you have two objects like this:
(B+A) and (C+B+A) with hierarchy between each other B->A and C->B->A. Super is just a way to ascend in the hierachy.
When you cast a C in A for example. In memory you always have an object (C+B+A) but interpreted as A. When you override you just say that a method in child has an higher priority than in parent.
You can try downcasting this manually to any of your class's predecessors. The pointer will still be equal to this but the methods called will use the class table of the class used to downcast.
public class Extended extends Base {
public function Extended() {
this.whoAmI() //prints extended
super.whoAmI() //prints base
var test:Base = this;
test.whoAmI() //should print base
}
public override function whoAmI() {
trace("extended");
}
}
Should your Base extend something, which methods are known or the superclass is dynamic, and there is code that adds methods to prototype of a class, you might use such a downcast to call a superclass's method that might not be there at compile time, but make sure you first call hasOwnProperty in case of a dynamic class to determine whether a method or property exists.

Register a single View as the View for Multiple ViewModels - MVVMCross

MMVMCross
Android
Windows 8
We had a View, call it FruitView displaying a ViewModel called FruitViewModel. The FruitViewModel can display lists of a particular type of fruit.
This all worked fine.
For a couple of reasons we created AppleViewModel and PearViewModel that inherit from FruitViewModel. They do not do anything, all calls are made to the base viewmodel.
I want to register the FruitView as the View for AppleViewModel and PearViewModel when I try and navigate to them using MvxNavigatingObject.ShowViewModel.
I cannot see how to override the default linking of Views to ViewModels. I read one post that suggested overriding GetViewModelViewLookup in the Setup class but that does not seem to exist. I also looked at CustomPresenters but that did not look like the right approach.
Anyone else done this?
Thanks
Pat
After spotting this question How to navigate to a ViewModel that extends an abstract class? (not one of the suggesting when i was posting) I found InitializeViewLookup that can be overridden in each platform's Setup.cs. I am augmenting the current mappings rather than replacing so have called base.InitializeViewLookup first.
protected override void InitializeViewLookup()
{
base.InitializeViewLookup();
var viewModelViewLookup = new Dictionary<Type, Type>()
{
{ typeof(AppleViewModel), typeof(FruitView) },
{ typeof(PearViewModel), typeof(FruitView) }
};
var container = Mvx.Resolve<IMvxViewsContainer>();
container.AddAll(viewModelViewLookup);
}
Thanks
Pat

MVVMCross - display view inside view

I cannot seem to find any simple examples of this.
I have a WPF UI that I wish to display a view as a child control within another view. The MvxWpfView inherits from UserControl so it should be possible, however I cannot seem to work out how to do the binding.
I get a BindingExpression path error, as it cannot find ChildView property in my ParentViewModel.
So how do I bind a view to control content?
Firstly it's possible that you just need to add the BViewModel you want displayed on AView as a property on ViewModelA
E.g.
public class AViewModel: MvxViewModel
{
public BViewModel ChildViewModel
{
get;set;//With appropriate property changed notifiers etc.
}
}
Then inside AView you just add a BView, and you can set the datacontext of BView as follows:
<UserControl DataContext="{Binding ChildViewModel}"/>
However, if you want something more flexible (and you want the presentation handled differently for different platforms) then you will need to use a Custom Presenter
Inside your setup.cs you override CreateViewPresenter:
protected override IMvxWpfViewPresenter CreateViewPresenter(Frame rootFrame)
{
return new CustomPresenter(contentControl);
}
Now create the class CustomPresenter you need to inherit from an existing presenter. You can choose between the one it's probably using already SimpleWpfPresenter or you might want to go back a bit more to basics and use the abstract implementation
The job of the presenter is to take the viewmodel you have asked it to present, and display it "somehow". Normally that mean identify a matching view, and bind the two together.
In your case what you want to do is take an existing view, and bind a part of it to the second view mode.
This shows how I have done this in WinRT - but the idea is very similar!
public override void Show(MvxViewModelRequest request)
{
if (request.ViewModelType == typeof (AddRoomViewModel))
{
var loader = Mvx.Resolve<IMvxViewModelLoader>();
var vm = loader.LoadViewModel(request, new MvxBundle());
if (_rootFrame.SourcePageType == typeof (HomeView))
{
HomeView view = _rootFrame.Content as HomeView;
view.ShowAddRoom(vm);
}
}
else
{
base.Show(request);
}
}
So what I'm doing is I'm saying if you want me to present ViewModel AddRoom, and I have a reference to the HomeView then I'm going to just pass the ViewModel straight to the view.
Inside HomeView I simply set the data context, and do any view logic I may need to do (such as making something visible now)
internal void ShowAddRoom(Cirrious.MvvmCross.ViewModels.IMvxViewModel vm)
{
AddRoomView.DataContext = vm;
}
Hopefully that makes sense! It's well worth putting a breakpoint in the show method of the presenters so you get a feel how they work - they are really simple when you get your head around them, and very powerful.

Linq to SQL - Turn off UpdateCheck in code

I am wanting to turn off the UpdateCheck functionality for all members (except their primary keys). Now I was following the example below as guidance, however my MetaDataMembers of the table are still set to Always.
http://www.the-lazy-coder.com/2013/04/set-updatecheck-to-never.html
The above code snippet just gets you to change the attribute, however it seems to never get picked up, as I can debug the code when it is running and I see all the properties being set, so I am presuming that the attributes changing does not change the underlying object.
Now if I were to change approach and just get the MetaDataMembers directly from the RowType I notice they have the UpdateCheck property, however only a getter. So is there a way to (via reflection if needed) overwrite this property once it is set? Even after looking at decompiled source it is an abstract class and I cannot find any implementations to use for reference.
I am using SQLMetal to generate the Context files, so there is no designer tinkering available, and although some people will say that I should run some text editing macros to parse and change the attributes, it all sounds too long winded when I should just be able to go into the object in memory and tell it to ignore whatever it has been told previously.
SO! Is there a way to override the property in the entities? I have tried running the original code in that link in both constructor, after the objects created and just before I am about to do an update, however none of the changes seem to stick or at least propagate to where it matters, and there is hardly any material on how to do any of this progmatically.
After searching around the internet I found no nice way to do it, and although there is the link I mentioned originally it doesn't work as it works on the attributes which are partly right but in the case above they are working on the attributes which are not in memory and are just the decorations, anyway the code below seems to work but is not nice:
public static void SetUpdateCheckStatus(this IDataContext dataContext, UpdateCheck updateCheckStatus)
{
var tables = dataContext.Mapping.GetTables();
foreach (var table in tables)
{
var dataMembers = table.RowType.DataMembers;
foreach (var dataMember in dataMembers)
{
if (!dataMember.IsPrimaryKey)
{
var dataMemberType = dataMember.GetType();
if (dataMemberType.Name == "AttributedMetaDataMember")
{
var underlyingAttributeField = dataMember.GetType().GetField("attrColumn", BindingFlags.Instance | BindingFlags.NonPublic);
if (underlyingAttributeField != null)
{
var underlyingAttribute = underlyingAttributeField.GetValue(dataMember) as ColumnAttribute;
if (underlyingAttribute != null)
{ underlyingAttribute.UpdateCheck = updateCheckStatus; }
}
}
else
{
var underlyingField = dataMember.Type.GetField("updateCheck", BindingFlags.Instance | BindingFlags.NonPublic);
if (underlyingField != null)
{ underlyingField.SetValue(dataMember, updateCheckStatus); }
}
}
}
}
}
The IDataContext is just a wrapper we put around a DataContext for mocking purposes, so feel free to change that to just DataContext. It is written extremely defensively as this way pulls back lots of members which do not have all the desired data so it has to filter them out and only work on the ones which do.