I am new to unit test. I am trying to create test case of a method which is calling an static method. For this static method I am getting "getting missing behaviour definition for the preceding method call:"
EasyMock can't mock static methods. So that's probably the problem. But having actual failing code will help providing a full answer.
I'm using ASDocs to make something like a "help" for my code and the problem is PRIVATE methods are omitted on ASDocs.
The thing is, on my project, I don't see any problems in change what is PRIVATE to PROTECTED. If I do that, the docummentation will be generated with everything I need.
So, the big question is: There's a problem have a project using only PROTECTED and PUBLIC methods and properties?
The problem that ASDoc omit private members makes sense. ASDoc used primarily to create documentation for API. Private members are not accessible from outside the class and cannot be inherited. So question are you really need ASDoc for private members?
And answer for your question about using only protected members: it breaks encapsulation, so it will be not good decision.
My main application swf file is being loaded by a simple loader swf application that is useful to break cache. In both applications I would like to have access to a singleton. I will provide you with an example to reproduce the bug. So here's our singleton:
package {
public class SingletonTest {
public static const instance:SingletonTest = new SingletonTest();
public function SingletonTest() { /* Nothing here. */ }
public function test():void {
trace("SingletonTest!");
}
}
}
In constructors of both loader and main classes I call:
SingletonTest.instance.test();
That is made in order to be sure that my singleton class code will be included in both applications. I won't provide you with loader code but it's very simple. It creates Loader instance, it creates LoaderContext supplying it with both current ApplicationDomain and SecurityDomain, etc...
But when I launch my loader application I get following error:
Main Thread (Suspended: TypeError: Error #1034: Type Coercion failed:
cannot convert SingletonTest#47a3091 to SingletonTest.)
SingletonTest$cinit
I get this error right after main application was loaded with loader. Event.COMPLETE is not dispatched yet so no handlers involved. I spent a lot of time trying to find something about application or security domains but it seems like it's not the issue because what I found next is really strange. If instead:
public static const instance:SingletonTest = new SingletonTest();
I will write:
private static var _instance:SingletonTest;
public static function get instance():SingletonTest {
if (_instance == null) _instance = new SingletonTest();
return _instance;
}
Then there will be no such error and everything will be fine. Obviously flash player is performing some unexpected behavior here. There's very few information on this issue out there. Most of people get this error because of missing loader context but as I said before here it's not the case. Some discussions on this are even left without any answers which is strange to me because I find this to be quite a common problem to be encountered when using small applcation loader.
Spent almost 12 hours trying to solve the problem. At last found the solution. In order to avoid runtime error which I provided above you need to compile your singleton class into swc-library. That's it.
In my case that singleton was providing global access to logging and only option was to switch from singleton pattern to static class. But I didn't want it very much because I really like this one-line singleton instantiation: "public static cosnt instance:MyClass = new MyClass();".
I have two questions about using the Comet feature with Glassfish. I'm
pretty new at this, so if there's an easy answer or some documentation
I should read please let me know! Thanks.
I'm building a system that has multiple microcontrollers sending data
to a central DB. Users view the data via their browsers ... in formats
(metric vs. English, say) of their own choosing. The display needs to
be updated without user action. It looks like Glassfish + Comet should
be perfect. And so I started with Oracle's "hidden_Comet" example, and
that works great.
So question #1 is this: how can one get session-specific information
into the "onEvent" method?
As context, here's the code; it’s straight from the Oracle example:
private class CounterHandler implements CometHandler<HttpServletResponse> {
private HttpServletResponse response;
public void onEvent(CometEvent event) throws IOException
{
if (CometEvent.NOTIFY == event.getType())
{
PrintWriter writer = response.getWriter();
writer.write("<script type='text/javascript'>");
[... etc. Here is where I need to pass some session-specific
info to the JavaScript]
event.getCometContext().resumeCometHandler(this);
}
}
It would seem that session attributes would be perfect, but it looks
like you can't get the 'session' variable from the "HttpServletResponse".
I thought about using cookies, but they seem to be accessible only with
HttpServletRequest, not "...Response", and, as above, only ‘response’
is available in the “onEvent” method.
So question #1 is: how do you do this?
Question #2 is: is this just the wrong way to attack this problem and is
there a better way?
I'm not sure I understand the data structures and control flow of Comet very well yet, but it seems that this works:
Add a constructor to "class CounterHandler" and pass in the 'session' variable from 'doGet()' where "new CounterHandler" is called. Specifically, change:
CometHandler handler = new CometHandler();
to
HttpSession session = request.getSession();
CometHandler handler = new CometHandler(session);
Have the constructor save the session variable in a class instance variable. And then the "onEvent()" method has access to session attributes. And Bob's your uncle.
(It seems straightforward enough ... well, now.)
I'm working with Progress 10.1c
I have a class that contains both static and non-static methods.
The class is defined with USE-WIDGET-POOL. In the destructor I say "DELETE WIDGET-POOL".
I create an instance of my class, and call a method. The method itself uses one of the static methods of the class. So if I understand it correctly, I will now have the instance of my class in its own unnamed pool, and a separate unnamed widget pool for the static members of the class.
So far so good. But I'm busy debugging and I'm making changes to the code. I recompile and run my test again. Now my non-static members work, but all the static members come from the older version of my class, that is still stored in the pool for static members, which is scoped to the session. In other words, the "DELETE WIDGET-POOL" in my destructor deleted the pool for the instance of the class, but the pool for the static members is still there.
The only way I can get it to load the new version of my class is to log off my session, and log on again. This is quite a mission in our environment. Every time I make a change, I have to stop and start my development environment.
I tried to walk the list of objects in my session, but could not find what I'm looking for. There's a good chance I'm starting at the wrong object, or I'm missing some knowledge of pools and objects in Progress.
Is there any way for me to target that unnamed pool and delete the static "instance" of my class, without destroying my session every time?
This turned out to be doable with very little coding. I can use the statement DELETE OBJECT THIS-OBJECT to delete the instance executing that statement. So if it's in a static method, it is the static instance that gets deleted.
METHOD STATIC VOID Reload () :
DELETE OBJECT THIS-OBJECT.
END METHOD.
So now when I have a new version of the class, I just use MyClass:Reload(). No need to end my session.
Thanks to Tim Kuehn for pointing me in the right direction with his suggestion of using a static method to delete the named widget-pool.
I have created this example to demonstrate how I got it to work. Below is a simple class with 3 static methods:
/* File : rtt/cls/demo.cls */
USING Progress.Lang.*.
ROUTINE-LEVEL ON ERROR UNDO, THROW.
CLASS rtt.cls.demo USE-WIDGET-POOL :
METHOD STATIC CHARACTER SayHello() :
RETURN "Good-bye".
END METHOD.
METHOD STATIC VOID ShowMessage() :
MESSAGE "This is the message." VIEW-AS ALERT-BOX.
END METHOD.
METHOD STATIC VOID Reload() :
DELETE OBJECT this-object.
END METHOD.
END CLASS.
I don't know how other people's environments are set up, but in my environment I have to log on to our system to be able to compile and run programs, in other words, I have an active session.
So I compile the file:
COMPILE VALUE(SEARCH("rtt/cls/demo.cls")) SAVE.
And then I run the following bit in Procedure Editor to test it:
USING rtt.cls.*.
demo:ShowMessage().
MESSAGE demo:SayHello().
When I run this, I get a message box that says "This is the message.", followed by a message box that says "Good-bye". Exactly as one would expect.
But there's a bug, it's supposed to say "Hello", not "Good-Bye", so I edit my class (I'm only showing the two methods I'm changing:
METHOD STATIC CHARACTER SayHello() :
RETURN "Hello".
END METHOD.
METHOD STATIC VOID ShowMessage() :
MESSAGE "That was the message." VIEW-AS ALERT-BOX.
END METHOD.
I save my changes, compile it as before, and I run the test again. What messages do you expect to see? I expect to see "This is the message." and "Good-bye", same as before. That's logical, because there is a hidden widget-pool in my current session, and it has an instance of my class loaded (from my first test). It will keep on using this instance until the instance or the pool is destroyed. So I shut down my development environment, log off and then log on again to start up a new session. So far everything is working exactly as expected.
Now I run my test again, and sure enough, I get my new version: the messages are "That was the message" and "Hello".
But now I'm told to add an exclamation after the word "Hello". so I change it:
METHOD STATIC CHARACTER SayHello() :
RETURN "Hello!".
END METHOD.
I save it and compile it. When I run the test, obviously I will get the older version that says "Hello" without the exclamation. I have to restart my session again before my changes become active. I really don't want to do that again. So I change my test as follows:
USING rtt.cls.*.
demo:Reload().
demo:ShowMessage().
MESSAGE demo:SayHello().
I run it and voilà, I get my latest changes. I change the message from "That was the message" to "It works!". I save, compile and run my test. What do I see? I see "It works!". No more restarting my session between edits. My solution works perfectly for me.
I tried all sorts of stuff, but I cannot get it to generate the error "Cannot Reference THIS-OBJECT or SUPER from a static member (15071)".
Static class elements last for the duration of the ABL session, and the only way to 'unload' them is to have a database connection go down (ie, the db server is shut down). This unloads everything, clears the client code, and leaves you in the 4GL editor.
Beyond that, the only other possible way is to create a named widget pool for the static class, then call a (static) method to delete that. I have no idea if this would work or not.
"Static members that are scoped to the class type. This unnamed widget pool is implicitly
deleted only when the ABL session in which the widget pool is created terminates."
http://documentation.progress.com/output/OpenEdge102b/pdfs/dvoop/dvoop.pdf
page 5-9
In this case make you something wrong. You should use the static members only for methods or properties, which are realy static and must be not deleted or reinitialised when is deleted the instance of class.
when you will use it anyway, you should define your own static widget-pool with name and any static dynamic objects create in this widget-pool. then can you in Reload() write:
METHOD STATIC VOID Reload () :
DELETE WIDGET-POOL XYZ.
CREATE WIDGET-POOL XYZ.
END METHOD.
other way is to use a singelton class, where are defined this 'static' objects. then anytime, when you will, you can delete the instance of this singelton and make some new fresh.