Number of parameters in method - java

I have Selenium test which fills a form. I have a method for it but this method has overgrown in terms of number of parameters -
newMerchantPage.addEditMerchant(merchantDomain, merchantName,
merchantCategory, true, merchantDescription, merchantNotes,
merchantTags, true, true, false, false, merchantTitle,
additionalDescription, merchantHeading, dummyCouponLink, true);
There are only Strings and boolean.
I was thinking to use collection and then iterate through collection in called method to do some more processing. Though yet not sure if this is the way to go about. Any recommendations?
MODIFIED METHOD:
After implementing couple of sugggestions my method (of a different method) call looks like -
ContactPage contactPage = new ContactPage(driver);
setContactFormData();
contactPage.setName(name).setEmailAddress(emailAddress).setSubject(subject).setM‌ ​essage(message);
contactPage.submitContactForm(contactPage);
submitContactForm in turn calls different utility methods. How bad does it look? Especially the last line (method call on object and same object being passed as argument) ?

One common approach is to wrap the parameters in a class. This class could then provide set-methods which return this to allow for a nice chaining. (See ProcessBuilder for a good example.)
Example:
MerchantData data = new MerchantData(); // initialize with sensible defaults
data.setDomain("example.com")
.setName("Some Name")
.setTags("tag1, tag2);
newMerchantPage.addEditMerchant(data);

I'm assuming that you are using Selenium server (or RC).
The suggestions for wrapping the data up into a Merchant class are all good and make sense, especially from pure Java coding point of view.
However, your main point of concern here in Selenium is the form you are filling, rather that the merchant domain object.
Maybe you could then break your method up into smaller methods such as
openMerchantForm(...)
typeNameInMerchantForm(...)
chooseMerchantCategory(...)
and so on, depending on what type of control is being set on the form. That will reflect the behaviour you are testing rather than setting the domain objects directly etc.
Hope that helps.

Maybe - write a class Merchant, create an instance with the method value and pass the instance instead?
newMerchantPage(Merchant merchant);
The advantage: you can keep the test parameters in files and do something like:
Merchant merchant = new Merchant();
merchant.populate(File testdata, int record);

Have you considered making a class that is if the parameters you specify belong to something same,then pass the object as the parameter.

Related

How to verify if an argument passed is with correct parameters if that argument's state is changed?

I'm trying to verify the object by using
#Captor
ArgumentCaptor<User> userArgumentCaptor
...//define user with name and jailName - var = user1
...//Call the method under test.
verify(userDao).getName(userArgumentCaptor.capture());
verify(userDai).getJailName(userArgumentCaptor.capture());
assertThat(userArgumentCaptor.getAllValues()).isEqualTo(Arrays.asList(user1user1));
/**
* Notice here that I had to use same object to verify even when I captured it in two different situations.
*/
for the scenario,
User user = new User(); //Object under inspection.
user.setId(); //Changing state here.
userDao.getName(user); //Capture user here.
...
if(someBooleanCondition) {
user.setJailStatus(true); //Changing state here.
userDao.getJailName(user); //Capture user here.
}
While asserting the userArgumentCaptor.getValue(), it is checking the updated value. This actually makes sense since I'm capturing the object not object's state.
But, how do I verify the object's state when it was passed?
I think this is not possible. Even when checking out the very latest version of ArgumentCaptor (mockito 2.7.21 at this point); there is no indication at all to go in that direction.
The purpose respectively service offered by ArgumentCaptor is to collect those parameters used when a method is called.
What you are asking is basically: is there a way to do additional checking at the point when that call happens.
I guess, it could be made possible: the framework would have to allow you to register a callback, that is called whenever a specific method is invoked on a mock object. But that isn't possible today.
The only solution I see - instead of doing
#Mock
YourRealDaoClass theMockedDao
You would have to do
class MockedDaoClass extends YourRealDaoClass {
and then implement such things yourself. So that you can put:
YourRealDaoClass theMockedDao = new MockedDaoClass(...
into your tests. Together with a some other logic to enable the things you need.
In other words: the mocks generated by Mockito do not allow you to do enhanced testing at the point when methods are invoked on mocked objects. If you need that (for example to do a test like: param.getFoo().equals()) then you are back to creating your own stub/mock class.
What you have to do:
carefully check all the methods that the Dao class has
decide which one you need to overwrite, to make sure that they return the values you need to make the mock work with your production code
for the methods that receive those parameters you are interested in: either do checking right there; or collect the values for later checking

Is there a way to serialize a method call

I am looking for a way to log a method call, store it in a database, and then at a later time execute it.
I was thinking to serialize the method call with all its arguments, store it, and then retrieve it back, deserialize it and execute it some how.
So, I am looking for a generic method that will allow me to store the method call with its arguments. Something like
public String myMethod(String arg1, String[] arg2) {
logMethodCall(thisMethodName, allMethodArgumentsSerialized)
}
and the logMethodCall would store the info in a database.
So
a) any code that will allow me to dynamically loop all arguments of a method and serialize them?
b) any code to get the current method name dynamically?
c) any other idea to accomplish something similar
This sounds like the Command pattern, where the actual command object is to be persisted (possibly serialized) before being executed:
command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters
Well, dare I say it, a natural language for handling stuff like this is Lisp. "Code = data", as they say.
If there is a requirement to use Java (for example, if this is to be a small part of a larger system already in Java), consider using ABCL (a Lisp implementation which targets the JVM).
You can spend a lot of time trying to wedge a square peg into a round hole, or just do it the easy way; it's your choice. I really don't mean this in a negative way; it's just an observation.
I haven't seen this pattern before, where you save method calls to the database. I have seen delayed method calls and throttled method calls, but those are always in the running app, they don't survive persistently.
If you want to have persistent actions that can be executed in the future, I think the right way to do this is to create some sort of action or edit object, in the same way that javax.swing.undo.AbstractUndoableEdit works. Then you can log these from anywhere, and execute them from anywhere. The actions can work in a few ways, including:
Store an object type, method name and generic arguments, and execute those later
Provide specific arguments and call a predetermined method name
I would go with the second with a base class, as Swing does, so from your example you would have a myMethodAction class whose objects take the arguments as properties and that knows when told to execute that it should call myMethod.
I would also not have the myMethod implementation do both things. That is going to be a huge headache later. Rather have something like
public void myMethod()
{
if(condition) ... save it ...
else myMethodNow();
}
public void myMethodNow()
{
... do the work now ...
}
Hope that helps.

work a function using dynamic strings?

I would like to save some work on my app, is it possible to get the string, for example "level1" and then use the corresponding function, which would be level1();? my main point is not to make a huge switch-case statement, but only make a few level functions in a storage class, and whenever you level up, the string would change to "level" + number where number is the int, so lets say that right now you are in level 10, the function that would run is level10();
I hope i explained it clearly.. sorry if not.. hope you get the idea!
Thanks!
I believe you want to call a method at runtime using its name as a string.
You can do it via reflection.
Class.getMethod(String methodName, Class... parameterTypes)
Don't think of this in terms of method names, unless you want to muck around with reflection (you don't want to, and it's not necessary).
If you really do need to convert strings to method calls – and that's a big "if" – create a Map<String, Foo> where Foo implements some "callable"-like interface. Then a string-to-method lookup is simply:
Map<String, Foo> commands = /* ... */;
Foo foo = commands.get("level42");
foo.bar();
It really sounds like you should just have a
void setLevel(int level)
call. That can feel free to ignore (say) levels 11-14 or whatever... but it would be very ugly to have separate methods and invoke them by name. You can do so with reflection, but you should think about other options first.
Please see the top answer to this post:
Java dynamic function calling
I would also recommend following their advice regarding structure, to create a more object-oriented solution instead of using reflection.

What is the best practice to modify an object passed to a method

After passing an object into a method, I would like to change one of its fields. What's the best practice to do this task in Java?
Simple answer
As stated in other answers, you can simply call the setter method.
More philosophical answer
Generally, it can be dangerous to mutate objects in a scope other than that in which they were created:
http://en.wikipedia.org/wiki/Functional_programming
That said, there are often times where you simply want to encapsulate bits of logic in the same logical scope where you would want to modify values of an object passed in. So the rule I would use is that as long as all calling code is fully aware of such mutations, you can call the setter method on the object (and you should create a setter method if you don't have one) in the method to which you're passing the object.
In general, if you call a function that mutates parameters from multiple places in your codebase, you will find that it becomes increasingly error prone, which is why functional programming pays off.
So, the moral of the story is: if your caller(s) are fully aware of such mutations, you could change the value in your method, but in general you should try to avoid it and instead change it in the scope in which it was created (or create a copy).
Be aware of the fact that even if the object is passed as final it still can be changed. You just can't reassign the variable, which normally is desired for an (input/)output parameter.
Taking Jigar Joshis example:
public void increasePersonAgeByOneMonth(final Person p ){
p = new Person(); //this won't work, which is ok since otherwise the parameter itself would not be changed by the next method
p.setAge(((p.getAge()*12.0) + 1)/12.0); //ok
}

If only one object field is required in a method, what should be passed as a parameter - an object or a field value?

Lets say there is a method that searches for book authors by book id. What should be passed as a parameter to such method - only book.id (int) or whole book object?
Or another example. In java I need to do some work with current url of the page. What should be passed to such method - only request.getRequestURL() or whole request?
I kind of see benefits from each method but can't come up with good rule when to use what.
Thanks.
I am not sure if there is a "rule" to what is best, but I most often pass just the paramaters I need into the method. So in your first example I would only pass in the book.id and in your second example I would only pass in the request.getRequestURL().
I try to avoid passing in more than I need.
I'm going to be a dissenter and argue for passing the entire Book object.
Reason 1: Type checking. If you just pass an integer ID, there's no way to know, looking at code, if you've got the correct "kind" of integer ID. Maybe you've been passing around an integer variable that you think is the Book ID, but it's actually the Author ID. The compiler is not going to help you catch this mistake, and the results are going to be buggy in unexpected ways.
Reason 2: Future proofing. Some have made the argument that if you just pass the ID, you give yourself the option to change the structure of the Book object later, without breaking the doSomethingWithBook(int ID) method. And that's true. On the other hand, if you pass the entire Book object, you give yourself the option to change the internals of doSomethingWithBook(Book book) (maybe it will want to search based on some other field in the future) without breaking any of the (possibly numerous) places you've called doSomethingWithBook. I'd argue that the latter helps you more.
In the case of the Request, I would give a different answer, since I would consider a Request object to be tightly linked to a certain type of interface (web) and therefore would want to limit the use of that object. One question I like to ask myself: if I wanted to switch this web application to be, say, a command-line application, how many classes would have to change? If I'm passing around the Request, that's going to "infect" more classes with web-specific logic.
Weaker connectivity is preferred unless there are specific reasons. When pass book id only to search method you are free to change Book interface without worrying that it might affect other functions. At some moment in future you may discover that you need to do exactly the same job with some URL outside request handler, so avoiding unneeded dependency on request is good. But note, that if you frequently call do_smth(request.getRequestURL()) it may become quite annoying.
This is related to the Law of Demeter, which basically states that objects and methods should only receive exactly what they need, rather than going through another object to get what they actually need. If you need to use multiple fields from a Book in your method, it might be better to just take a book. But in general, you'll have less coupling in a system if you only depend on exactly what you need.
In both your examples, just using the ID or URL would probably be preferable. Particularly in the case of the URL, where (if you want to test the method) it's easy to create a URL to test with but harder (and completely unnecessary) to create a request to pass to the method which will then only use the URL anyway. The method also becomes more generally applicable to other situations than one in which you have a request object.
I would give each method only as much as necessary (so for the second question: just give it request.getRequestURL()).
For the first one I would think about defining both methods (but prefer the id-one, as you can easily get the ID if you have a Book, but not the other way around).
findAuthorsForBookId(int bookId)
findAuthorsForBook(Book b)
Call book.authors().
(Note: this is a dissenting view regarding the accepted answer.)
Well, there is an implicit rule set in context of domain modeling. If the receiver is performing tasks independent of the domain model then you pass the field. Otherwise, you should pass the object and the model specific action is made explicit by the act of the receiver accessing the id property of the 'Book' object. Most importantly, if accessing the property ever evolves beyond simply returning the reference of a field (e.g. certain actions in the property accessor) then clearly you do NOT want to chase all instances in your code where you dereferenced the property before passing it into various methods.
Further considerations are the consequences (if any) of accessing the field before the call cite, or, inside the receiver.
There's no rule actually, you should be straightforward with the info you need, in that case the book.id. If you consider extending / sharing your search in the future, the you can have an overloaded method to accept a book object so that you can search by other attributes of the book object.
Think about maintaining the code in the long run. Any method you expose is a method you'll have to support for your users going forward. If bookId is all that's needed for the forseeable future, then I'd go with just passing in that: that way, anyone who has a bookId can use your method, and it becomes more powerful.
But if there's a good chance that you may need to refactor the lookup to use some other attributes of Book, then pass in Book.
If you're writing a DAO of sorts, you should consider having a BookSelector which can be built up like: new BookSelector().byId(id).bySomethingElse(somethingElse) and pass this selector instead of having a proliferation of findByXYZ methods.
I agree with the previous posters. I wanted to add that if you find yourself needing multiple properties of the object (id, title, author) then I'd suggest passing the object (or an interface to the object). Short parameter lists are generally preferable.
Lets say there is a method that searches for book authors by book id. What should be passed as a parameter to such method - only book.id (int) or whole book object?
I am making the assumption that "book authors" is an attribute of a book. Therefore, I imagine something like the following class:
class Book {
private int id;
private List<Author> authors;
// ... maybe some other book information
public int getID() {
return this.id
}
public void setID(int value) {
this.id = value
}
public List<Author> getAuthors() {
return this.authors.clone();
}
// ...
}
Given an instantiated Book object (aBook), to determine the list of authors, I would expect that I can call aBook.getAuthors(), which requires no parameters.
I would discourage the creation of partially instantiated domain objects. In other words, given a bookid, and looking for a list of authors, I would want the client code to look more like this:
Book aBook = library.findBook(bookid);
List<Author> authors = aBook.getAuthors();
and less like this:
Book bookQuery = new Book().setID(bookid); // partially instantiated Book
Book aBook = library.findBook(bookQuery);
List<Author> aBook = book.getAuthors();
The first version reduces the number of throwaway objects that are created by the client code. (In this case, bookQuery, which isn't a real book.)
It also makes the code easier to read--and therefore to maintain. This is because bookQuery is not doing what the maintenance programmer would expect. For example, I'd expect two Books with the same ID to have the same tite, authors, ISBN, etc. These assertions would fail for bookQuery and aBook.
Thirdly, it minimizes the chance that you will someday pass an invalid (partially instantiated) Book object to a method that is expecting a real Book. This is a bug where the failure (in the method) may happen far away from the cause (the partial instantiation).

Categories

Resources