I have a property in my controller that I would like to test:
public List<SelectOption> exampleProperty {
get {
//Do something;
}
}
I am not sure how to cover this code in my test class. Any ideas?
There is direct way, just invoke the property from test method
List<SelectOption> temp = obj.method;
You may need to directly test your properties, especially if you use lazy initialization - a smart pattern for making code efficient and readable.
Here's a list example of this pattern:
Integer[] lotteryNumbers {
get {
if (lotteryNumbers == null) {
lotteryNumbers = new Integer[]{};
}
return lotteryNumbers;
}
set;
}
If you wanted full coverage of the pattern (which may be a good idea while you're getting used to it), you would need to do something like the following:
static testMethod void lotteryNumberFactoryText() {
// test the null case
System.assert(lotteryNumbers.size() == 0);
Integer[] luckyNumbers = new Integer[]{33,8};
lotteryNumbers.addAll(luckyNumbers);
// test the not null case
System.assert(lotteryNumbers == luckyNumbers);
}
First off, do you really want to have an attribute named "method"? Seems a helluva confusing. Anyway, to cover the code, just call
someObject.get(method);
But code coverage should be a side effect of writing good tests - not the goal. You should think about what the code is supposed to do, and write tests to check (i.e. assert) that it is working.
Related
I've recently taken upon myself to add setter and getter methods to my class.
Since doing this, many parts of my code got broken and I'm unable to access getter methods.
Take the example below:
private loadInputs() : Input[] {
var inputs = <Input[]>this.get('inputs');
inputs.sort((a,b) => a.QuoteRef().localeCompare(b.QuoteRef()))
return( inputs || [] );
}
My input class has 2 variables,
_Project: string
_line: string
Which I access using a method QuoteRef()
public QuoteRef(): string {
return this._Project.concat('-' + this._Line.toString().padStart(3,'0'));
}
Whenever I try to access a method or a getter from my class on an item that is casted as an Input, I can see the variables (though not access them as they are private), but the prototype section doesn't contain any of the methods.
This triggers the following error in the website console:
TypeError: a.QuoteRef is not a function
What am I doing wrong?
Update
I got it to work by updating the code as follows:
inputs.sort((a,b) => {
let first = new Input(a);
let second = new Input(b);
return first.QuoteRef().localeCompare(second.QuoteRef());
});
Without seeing your complete class I can only guess, but I think that a and b in your sort are not of the type you expect. I can't see what this.get('inputs') does, but I suspect it is not returning an array with Input class objects. Hence the function cannot be found (is not a function). You could try:
inputs.sort((a,b) => {
console.log(typeof a);
console.log(typeof b);
a.QuoteRef().localeCompare(b.QuoteRef());
})
and check what the type is. Then check what your this.get actually returns.
Edit: forgot to mention that your IDE probably does not warn you because you cast the output of this.get to <Input[]>.
I'm looking for a clean way to translate complex logical conditions with if and else statements that lead to different actions, into lambdas and streams.
Suppose I have this code:
List<OuterData> result = new LinkedList<>();
for (Outer outer : getOutersFromSomewhere()) {
OuterData outerData = new OuterData();
if (outer.isImportant()) {
doImportantAction(outer, outerData);
} else if (outer.isTrivial()) {
doTrivialAction(outer, outerData);
} else {
doDefaultAction(outer, outerData);
}
for (Inner inner : outer.getInners()) {
if (inner.mustBeIncluded()) {
InnerData innerData = new InnerData();
if (inner.meetsCondition1()) {
doAction1(inner, innerData, outer, outerData);
} else if (inner.meetsCondition2()) {
doAction2(inner, innerData, outer, outerData);
} else {
doDefaultAction(inner, innerData, outer, outerData);
}
outerData.add(innerData);
}
}
result.add(outerData);
}
return result;
This is simplified from real code I have. I know it can be optimized and refactored, i.e. I could move inner for to a private method. I'd like to know how to translate the if, else if and else parts to streams and lambdas.
I know how to translate the skeleton of this example. I'd use List.stream(), Stream.map(), Stream.filter(), Stream.collect() and Stream.peek(). My problem is with conditional branches only. How can I do this translation?
One first obvious way is to stream your elements, filter them according to the needed criteria, and then applying the action on each remaining element. This also makes the code much cleaner:
List<Outer> outers = getOutersFromSomewhere();
outers.stream().filter(Outer::isImportant)
.forEach(outer -> doImportantAction(outer, outerDate));
outers.stream().filter(Outer::isTrivial)
.forEach(outer -> doTrivialAction(outer, outerDate));
// default action analog
Caution: This only works if the important, the trivial, and the default elements form a partition. Otherwise it is not equivalent to your if-else-structure. But maybe this is intended anyway ...
The main problem with this approach: It is not very good OOP. You are querying the objects in order to make a decision. But OOP should be "tell, don't ask" as much as possible.
So another solution is to provide a consuming method in your Outer class:
public class Outer {
...
public void act(OuterData data, Consumer<Outer> importantAction,
Consumer<Outer> trivialAction, Consumer<Outer> defaultAction) {
if (isImportant())
importantAction.accept(this, data);
else if (isTrivial())
trivialAction.accept(this, data);
else
defaultAction.accept(this, data);
}
}
Now you call it as simple as this:
List<Outer> outers = getOutersFromSomewhere();
outers.forEach(outer -> outer.act(...)); // place consumers here (lambdas)
This has a clear advantage: If you ever have to add a feature to your Outer class - let's say isComplex() - you have to only change the internals of that single class (and maybe resolve the compiler failure in other parts). Or maye you can add this feature in a backward compatible way.
The same rules can be applied to the Inner class and the iteration.
I have a method as follows
public class ClientClass {
public void clientMethod() {
while(true){
doSomethings.....
}
}
}
I am trying to test using mockito. I am able to make the call to clientMethod, but since there is a while(true) inside clientMethod, the call never returns and I never reach to my assert statements which (of course) occur after clientMethod() invocation.
Is there a way to stop the loop after one loop iteration from my test case?
Technicaly you can't break the infinite loop in test without throwing an exception from inside it. If there is something inside the loop you can mock, then it may produce an exception for you.
When you're finding yourself in situation like this, when awkward workarounds are necessary for testing, then it's time to stop and think about the design. Non-testable code is generaly ill-maintainable and not very self-explanatory. So my advice would be to get rid of infinite loop and introduce an appropriate loop condition. After all, no application will live forever.
If you're still convinced that endless loop is the best way to go here, then you can perform a slight decomposition to make things more testable:
public class ClientClass {
// call me in production code
public void clientMethod() {
while(true){
doSomethings();
}
}
// call me in tests
void doSomethings(){
// loop logic
}
}
This was a source of a little frustration to me... because I like to start off the most sophisticated of GUI apps with a console handler.
The language I'm using here is Groovy, which is a sort of marvellous extension of Java, and which can be sort of mixed in with plain old Java.
class ConsoleHandler {
def loopCount = 0
def maxLoopCount = 100000
void loop() {
while( ! endConditionMet() ){
// ... do something
}
}
boolean endConditionMet() {
loopCount++
loopCount > maxLoopCount // NB no "return" needed!
}
static void main( args ) {
new ConsoleHandler().loop()
}
}
... in a testing class (also in Groovy) you can then go
import org.junit.contrib.java.lang.system.SystemOutRule
import org.junit.contrib.java.lang.system.
TextFromStandardInputStream.emptyStandardInputStream
import static org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import static org.mockito.Mockito.*
class XXTests {
#Rule
public SystemOutRule systemOutRule = new SystemOutRule().enableLog()
#Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream()
ConsoleHandler spyConsoleHandler = spy(new ConsoleHandler())
#Test
void readInShouldFollowedByAnother() {
spyConsoleHandler.setMaxLoopCount 10
systemInMock.provideLines( 'blah', 'boggle')
spyConsoleHandler.loop()
assertThat( systemOutRule.getLog() ).containsIgnoringCase( 'blah' )
assertThat( systemOutRule.getLog() ).containsIgnoringCase( 'boggle' )
The beautiful thing that's happening here is that simply by declaring maxLoopCount the language automatically creates two methods: getMaxLoopCount and setMaxLoopCount (and you don't even have to bother with brackets).
Of course the next test would be "loop must exit if a user enters Q" or whatever... but the point about TDD is that you want this to FAIL initially!
The above can be replicated using plain old Java, if you must: you have to create your own setXXX method of course.
I got stuck in this because I was calling same method from inside the method by mistake.
public OrderEntity createNewOrder(NewDepositRequest request, String userId) {
return createNewOrder(request, userId);
}
I want to find a way to only allow certain objects into an array that have a certain word in thier class name. Or at least find the optimal way of doing something like this. Heres the details. I have an Array that stores all the objects dropped into a cart.
function addProductToArray (e:MouseEvent):void{
currMC = (e.target as MovieClip);
myCart.itemsInCart.push(currMC);
trace(myCart.itemsInCart);}
If, for example, I drop an [object BreadGrain] and a [object PastaGrain].
trace(myCart.itemsInCart);// would trace [object BreadGrain],[object PastaGrain].
Easy, no problems there. But what do I do if I only want to allow 2 objects with "Grain" in their Classname into the array? I want to do this so that the user can only drop 2 of each type of food into the 'cart'. The types of food are Grain, Fruit, Vegetable, Meats etc and I've appended the type of food to the end of the Classname, hopefully so that I can use it to detect what type of food it is and stop it from being added over the limit as well as displaying an error. i.e "You already have 2 Grain products".
I hope that makes sense. Anyway, i've found that works well to a degree:
if (currMC is BreadGrain) {
myCart.itemsInCart.push(currMC);
} else {
// error message code here
}
BUT I have several products and I don't want to have to write a if/else or switch statement for them all. I was hoping to do this dynamically with something similar to:
//this is an example of the logic
if (currMC classNameContainsTheWord "Grain" AND myCart.itemsInCart DoesNotContainMoreThan 2 Grain Objects) {
myCart.itemsInCart.push(currMC);
} else {
// error message code here
}
I'm stumped. Even just a "Dude, you are doing this all wrong" would help. Thanks.
You can get the class name of any object with the getQualifiedClassName function. Then you could try to match strings agains a certain pattern, with a RegExp or you could also just check if the class name contains some substring.
That said, I think a better approach could be using either a common base class or an interface.
// assuming your objects extend MovieClip
public class Grain extends MovieClip{
public function Grain() {
super();
}
public function someCommonMethodToAllGrains():void {
}
}
or
// It's customary to prefix interfaces name with an "I" in AS;
// I'm not doing it here so the code works for both a base class and an interface
public interface Grain {
function someCommonMethodToAllGrains():void;
}
Then, if you went with the base class:
public class BreadGrain extends Grain {
public function BreadGrain() {
super();
}
override public function someCommonMethodToAllGrains():void {
// if this makes sense for your object...
super.someCommonMethodToAllGrains();
}
}
public class PastaGrain extends Grain {
public function PastaGrain() {
super();
}
override public function someCommonMethodToAllGrains():void {
// if this makes sense for your object...
super.someCommonMethodToAllGrains();
}
}
Or, with the interface
public class BreadGrain extends MovieClip implements Grain {
public function BreadGrain() {
super();
}
public function someCommonMethodToAllGrains():void {
}
}
public class PastaGrain extends MovieClip implements Grain {
public function PastaGrain() {
super();
}
public function someCommonMethodToAllGrains():void {
}
}
If these objects are MovieClips, perhaps it's less tedious to use a base class, because otherwise you'd have to cast your objects back to MovieClip (or DisplayObject) any time you want to add them to the display list (or remove them). By the way, that's because someone at Adobe forgot to include an IDisplayObject interface and have the display list API accept objects that implemented this interface instead of a half-assed abstract class that you can't derive directly anyway (a.k.a. DisplayObject); this would have make it easier to treat display objects as interfaces, but I digress).
Anyway, either with an interface or a common base class you could do your validation with the is operator, but you'd just have to check for one type: Grain.
if(theObject is Graing && theArray.lenght <= 2) {
theArray.push(theObject);
}
You could also take this further and use a Vector instead of an Array. A Vector works almost the same as an Array, but it's strictly typed, so you could do:
var items:Vector.<Grain> = new Vector.<Grain>();
items.push(grainObject);
You'll get a compile time error if you try to add an object that does not extend/implement Grain.
Vectors are available for Flash Player 10 and you'd need Flash CS4, though (if you're using the Flash IDE; otherwise, I think you'd need at least the 3.2 SDK to compile).
Hm. I think you're going to need something a bit more complex to make this work properly. You're actually asking a two-part question: how to keep track of stuff, and how to identify stuff. I'll start with the easy bit, keeping track.
DISCLAIMER: My AS3 is pretty rusty, but at least the theory should be sound, even if the implementation might be a bit off.
First, you'd want to define the limits for each type of food, thus:
var dctLimits = new Object(); // not really a Dictionary, but we'll use it like one
dctLimits[ "grain" ] = 3;
dctLimits[ "meat" ] = 5;
...
Then, you want to keep count of objects you're adding to your cart
var dctCount = new Object();
dctCount[ "grain" ] = 0;
dctCount[ "meat" ] = 0;
...
Then, when you add a new object, first check its type against the relevant count. If the counter is less than the limit, let it in and increment the counter:
var type:String = getFoodTypeForObject( currMc );
if( dctCount[ type ] < dctLimit[ type ] ){
items.push( currMc );
dctCount[ type ]++;
} else {
// throw error
}
You'll notice that I've created an imaginary function, getFoodTypeForObject(). This is the trickier bit: identification.
You could implement your example logic like so:
function getFoodTypeForObject( currMc ){
if( getQualifiedClassName( currMc ).indexOf( "Grain" ) > -1 ){
return( "grain" );
} else if( getQualifiedClassName( currMc ).indexOf( "Meat" ) > -1 ){
return( "meat" );
}
...
}
Where classNameContainsTheWord is achieved with a combination of getQualifiedClassName and indexOf, but better would be to use a common base class, as suggested by Juan Pablo Califano. I'd suggest a slightly different style though:
public class CartItem extends MovieClip{
public var isGrain:Boolean;
public var isMeat:Boolean;
public function CartItem() {
super();
}
}
use that as the base Class for your cart item MCs, then set those boolean properties on the instances of MCs on your stage. Then, you can detect the type of something like this:
function getFoodTypeForObject( object ){
if( object.isGrain ){
return( "grain" );
} else if( object.isMeat ){
return( "meat" );
}
...
}
Cleaner than all that classname business, and has the added benefit that you can set something's properties independent of its class name.
It's not perfect; for instance, you'd need something more advanced if you needed a lot of properties, but it should be enough for you to keep going.
Uni had me doing other stuff for a while but finally I can get back into my game project.
I've got it working. I used Juan Pablo Califano's method. I did initially use Henry Cooke's because I wanted to get away with making a .AS file for each food (i.e. apple.as, cereal.as, bread.as, oranges.as). With Henry Cooke's method I created a
`var foodTypeLimit:Object = new Object();
foodTypeLimit["grain"]=2;
foodTypeLimit["fruit"]=2;
And var foodTypeCount:Object = new Object();
etc etc
`
For each food type. Then used the:
var type:String = getFoodTypeForObject( currMc );
if( foodTypeCount[ type ] < foodTypeLimit[ type ] ){
items.push( currMc );
foodTypeCount[ type ]++;
} else {
// throw error
}
As suggested. The function returned the string and viola it worked fine. However because my foodTypeCount variables (for example foodTypeCount["grain"]=0;) was inside the function, every time the function called these were set to 0 so the increment never got above with each call. So I thought, ok, i'll put these foodTypeCount variables outside of the function along with the instantiation of the var foodTypeCount:Object = new Object(); BUT NO, I kept getting the:
Error #1120: Access of undefined property foodTypeObject.
Even though it was right under the freakin declaration. I get i'm just too noob to understand why this is so. Anyway, for this reason (the lack of incrementation, which was essential to this function) I bit the bullet and used Juan Pablo Califano's way.
First I wrote out the classes like so:
public class Bread extends MovieClip implements Grain {
public function Bread() {
super();
}
public function someCommonMethodToAllGrains():void {
}
}
And then added the interface
`public interface Grain {
function someCommonMethodToAllGrains():void;
}
`
And now my function looks something like this:
if(currMC is Grain){
if(grainCount<2){
addProductToBasket();
grainCount++;
} else {
notAllowed("Grain");
}
}
function addProductToBasket(){
removeChild(currMC);
basketArray.push(currMC);
//remove listeners set mc to null etc
}
function notAllowed(foodType:String){
error.text="Sorry but you already have 2"+foodType+"products";
}
I tried to put all this into a switch. For example:
switch(currMC){
case is Grain:
//do this
break;
}
The above implementation didn't work. Perhaps switch statements probably aren't meant to be used that way. idk. :S
Anyway, thanks for the really great answers guys, this is my favorite site to come to for answers to life the universe and everything.
I have a method DoCleanUp(), which will ask user to proceed and then clear current workspace. It will return if user choose to cancel this process.
My question is, which signature is best to indicate a "cancel"?
bool DoCleanUp(); // return false to indicate canceled.
bool DoCleanUp(); // return true to indicate this method should be canceled.
void DoCleanUp(bool& cancel); // check parameter 'cancel' to see if this method was canceled.
UPDATE: As for the language, it's C++\CLI or C#.
UPDATE2: Now suppose I have to save a file in the DoCleanUp method. I'll prompt a dialog ask user whether to save/not save/cancel the file. Based on the answers, here is what I came up:
void DoCleanUp();
DialogResult AskToSaveFile(); // return yes/no/cancel
void DoCleanUp( bool saveFile );
Usage:
void DoCleanUp()
{
DialogResult result = AskToSaveFile();
if( result == DialogResult::Cancel ) return;
bool saveFile = (result == DialogResult::Yes) ? true : false;
DoCleanUp( saveFile );
}
Then by calling DoCleanUp(), you know user will have the opportunity to cancel;
By calling DoCleanUp(bool saveFile), you can control whether to save file without asking user.
Is that looks better?
This is a classic single responsibility problem.
The reason that you are unsure about the signature is that the method is doing 2 things.
I would create 2 methods:
bool CheckIfTheUserWantsToCancel()
void DoCleanUp()
EDIT
Based on the comments and edits to the question I would create a 3rd method:
void SaveFile()
The DoCleanUp would then first call CheckIfTheUserWantsToCancel, and then if not cancelled would call SaveFile.
IMHO this is much better than trying to remember that DoCleanUp with parameter false will save the file without asking the user, or was it the other way around?
Without more details I would say answer 1 is the best IMHO. Third is rather ugly since it requires more code for calling.
But maybe consider rewriting code to this
void CleanUp() {
switch (AskUser()) {
case ButtonOk: CleanUpDesk(); break;
case ButtonNo: break;
default:
case ButtonCancel: CancelCleanUpDesk(); break;
}
}
This seems to in the spirit of single responsibility. My code somehow breaks your problem into two steps: asking user and performing action.
I would use your 1 version.
bool DoCleanUp(); // return false to indicate canceled.
The assumption is, that it returns true when the cleanup is done. Returning false would indicate a 'Error' state. It might even make sense to return an int. In this case the convention usually is that 0 represents success and everything else is an error code.
Regardless of what you decide, document what your return values mean!
The confusing bit is the calling it DoSomething(), when it might not do anything. How about
if (QueryCleanup()) // boolean
DoCleanup(); // void
More verbose but clearer, even without seeing the declaration.
You should not use a boolean for statuses (or status messages). Create an Enum:
public Enum CleanupStatus
{
Ok = 0,
Cancel
}
This way it is more clear what the return value is ... and if you need to add more statuses, you can.
(This is all from Code Complete 2, you should read it if you haven't yet.)
You have two requests basically. The outer request is to create a new workspace. The inner request is to save the current workspace. You want to return true if the outer request continues and false if the outer request is aborted. The action of the inner request is not important to the outer request and so should be some kind of delegate/functor/closure.
Make a class to genericize this:
class YesNoCancel {
string question; // question to ask the user about the inner state
delegate doit; // function to call to
delegate dontdoit;
public:
YesNoCancel(string question, delegate doit, delegate dontdoit = null) {...}
bool run() {
switch (AskUser(question)) {
case ANSWER_YES: doit(); return true;
case ANSWER_NO: return true;
case ANSWER_CANCEL: if (dontdoit) dontdoit(); return false;
};
//usage
void NewWorkspace() {
if (m_workspace) {
YesNoCancel ync("Save current workspace?", saveworkspace);
if (!ync.run()) return;
}
// new workspace code
}
void CloseApp() {
YesNoCancel ync("Save current workspace?", saveworkspace);
if (ync.run()) ExitApplication();
}
I believe option three gives the most clarity. When you have the bool as a return type it is not immediately clear what it is used for.
I usually go with
bool DoCleanUp(); // Returns true if cancel
but mostly it depends on whether the calling code looks like this:
if (DoCleanUp()) {
// Do cancel up code
}
or:
if (DoCleanUp()) {
// Do non-cancel post clean up code
}
Basically I try to make my tests not have to use a ! or language equivilent as I find it hard to see.
I definitely would not do number 3.
I prefer the third signature, only because by looking at it (without any extra documentation), I can tell more about what the method does. I would call the argument something more explicit, like processCancelled, though.