Test a method without initialize the class - java

I'm very new to unit testing, I'm wondering if there is a way to test a method without initializing the class. The reason I'm asking is because there are lot of object passing in the constructor meaning a lot of mocking stubbing while from a thorough check methodToTest seems not to use any object attribute. It's not my code otherwise the method could be converted to static.
class ExampleClass {
public ExampleClass(FirstClass fc, SecondClass sc, ThirdClass tc) {}
public void methodToTest(FourthClass foc) {}
}

You have some options here:
Make the method static so you don't need a reference to an actual object. This will only work if the method does not need any state of ExampleClass (i.e. everything it needs is passed in the method arguments).
Extract this method to another class (perhaps using the method object pattern) that's easier to test on its own. This refactoring is called replace method with method object.

Usually, having to many parameters in constructors is a hint on bad conception. You'd better rethink you Objects and classes to reduce argument to give to the constructor.
If you don't want to, you can still use some kind of a "TestUtil" wich instantiate class for you.
Example :
public class MyTestUtils {
public createValidFirstClass() {
return new FirstClass(/* some arguments here */);
}
public createValidSecondClass() {
return new SecondClass(/* Some arguments here */);
}
public createValidThridClass() {
return new ThridClass(/* Some arguments here */);
}
public createValidExampleClass() {
return new ExampleClass(createValidFirstClass(), createValidSecondClass(), createValidThridClass());
}
}
This class MUST be in your test packages and not in your project, and should not be used outside of the tests, it would be a really bad practice here, use Factory or Builder for your real projects.
Anyway, i think that the best solution is to rethink you Classes.
Example :
public class People {
public People(String firstName, String lastName, Date birth, Date death) {
}
}
As you can see this is a pain in the ass to control that all given parameter was correctly formatted and not null.
This number of argument passed to a method can be reduced this way.
public class People {
public People(PeopleNames names, Period period) {
}
}
public class PeopleNames {
public People(String firstName, String lastName) {
}
}
public class PeopleNames {
public People(Date begin, Date end) {
}
}

Ok, it seems I found a way. Since the method is irrelevant to the state of the object, I could mock the object and order the MockRunner to use the real method when it is called. It is named partial mocking. The way of doing it is
ExampleClass = PowerMockito.mock(ExampleClass.class);
when(ExampleClass.methodToTest(foc)).thenCallRealMethod();

As far as I know, you cannot conduct a Test without initializing the class.
The three steps of Test are Arrange,Act and Assert. The class has to be initialized in the arrange part for fetching the required methods in the particular class you are testing.

I don't know what your method does but if it's possible for your application you could just make methodToTest static, which would allow you call it without an instance of the class.
Alternatively, you could avoid too much instantiation by creating one instance in a #BeforeClass method to be used for all tests, but again I don't know what you method does so that might not be desirable.

Use suppressions from PowerMockito.
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.api.support.membermodification.MemberMatcher;
suppress(MemberMatcher.constructor(ExampleClass.class))

Related

Does it make sense to have a non static method which does not use an instance variable?

The compiler does not let a static method call a non static method. I understand it does this because a not static method usually ends up using an instance variable.
But does it make sense to have a non static method which does not use an instance variable. If we have a behavior which does not affect or isn't affected by the instance state , shouldn't such a method be marked as static.
Well sure! Let's assume that you have in interface IMyCollection. It has a method boolean isMutable().
Now you have two classes, class MyMutableList and class MyImmutableList, which both implement IMyCollection. Each of them would override the instance method isMutable(), with MyMutableList simply returning true and MyImmutableList returning false.
isMutable() in both classes is an instance method that (1) does not use instance variables, and (2) does not affect instance state. However, due to constraints in the language (it's impossible to override static methods), this design is the only practical one.
Also, I would like to clear up a misconception (as #manouti did as well): non-static methods aren't instance because they use any instance variables or affect instance state; they're instance methods because they were defined that way (without the static keyword), and thus have an implicit this parameter (which, in languages like Python, is actually explicit!).
Often times, no. If the method doesn't touch any instance state, there's no reason to tie it to an instance.
Of course, static methods can't be inherited or overridden, so that's one obvious time that you would want to have an instance method that doesn't use instance state. The strategy pattern is a classic example of this.
Another case where you may tie it to an instance anyway is if this is a public API and you imagine that you may want to tie the method to instance state in the future. In that case, backwards compatibility concerns for people who are using your API may make it difficult (or impossible) to turn that static method into an instance method.
Because static methods cannot be overridden, many developers that are concerned about testability of their code try to avoid static methods in Java altogether.
Code is more testable if dependencies can be replaced with mock objects. Mockito and EasyMock are the most common tools to help with this, and they rely on inheritance to create subclasses that allow you to easily override the (often complex) method that you don't want to test ... so that your test is focused on what you do want to test.
I don't go to the extreme of trying for zero static methods, but when I concede to include them, I often regret it later, for testing reasons.
All of this is very frustrating, because it has nothing to do with what ought to be the design consideration of static vs instance methods. Which makes me wish for those languages that allow you have have functions that aren't connected with a class ...
If one were writing a human-readable description of the method's purpose, would it make mention of an object? If so, use an instance method. If not, use a static method. Note that some methods might be described either way, in which case one should use judgment about which meaning is better.
Consider, for example, "Get the address to which a Freedonian income tax form should be mailed" vs "Get the address to which Freedonian income tax forms should be mailed"? The first question should be answered by an instance method; the second by a static method. It may be that Freedonia presently requires all tax forms to be sent to the same address (in which case the former method might ignore all instance fields), but in future may have different offices for people in different regions (in which case the former method might look at the taxpayer ID and select a mailing address based upon that, while the latter method would have to direct forms to an office which could accept forms for anyone and redirect them as needed).
I understand it does this because a not static method usually ends up using an instance variable.
Even if the instance method does not use an instance variable, it is still bound to the instance of the class. In fact, it has a reference to this implicitly in the method arguments.
In other words, in the following method:
public void foo() {
}
this is implicitly passed as the first local variable in the method.
EDIT:
Re-reading the question, it's more of a broad question that depends on the situation. Generally if the method does not need the instance (and you're pretty sure it won't), then just make it static.
A nice example is an object-oriented encoding of booleans. Most languages, even object-oriented ones like Java, opt for an Abstract-Data-Type-oriented encoding of booleans, but e.g. Smalltalk uses an OO encoding, and almost none of the methods make use of any instance state. It looks a bit like this:
import java.util.function.Supplier;
#FunctionalInterface interface Block { void call(); }
interface Bool {
Bool not();
Bool and(Bool other);
Bool or(Bool other);
<T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch);
void ifThenElse(Block thenBranch, Block elseBranch);
static final Bool T = new TrueClass();
static final Bool F = new FalseClass();
class TrueClass implements Bool {
public Bool not() { return F; }
public Bool and(Bool other) { return other; }
public Bool or(Bool other) { return this; }
public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
return thenBranch.get();
}
public void ifThenElse(Block thenBranch, Block elseBranch) {
thenBranch.call();
}
}
class FalseClass implements Bool {
public Bool not() { return T; }
public Bool and(Bool other) { return this; }
public Bool or(Bool other) { return other; }
public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
return elseBranch.get();
}
public void ifThenElse(Block thenBranch, Block elseBranch) {
elseBranch.call();
}
}
}
public class Main {
public static void main(String... args) {
Bool.F.ifThenElse(() -> System.out.println("True"), () -> System.out.println("False"));
// False
}
}
In fact, if you follow a serious commitment to OO, use a lot of referentially transparent methods, and favor polymorphism over conditionals, you will often end up with methods in lots of subclasses, where each implementation in one of the classes returns a constant value.
I think sometimes it is yes,because non static method can override to do different tasks for different class,but the task may not involve instance variable,e.g.:
Fruit.java
public class Fruit{
public void printInfo(){
System.out.println("This is fruit");
}
}
Orange.java
public class Orange extends Fruit{
public void printInfo(){
System.out.println("This is orange");
}
}
Grape.java
public class Grape extends Fruit{
public void printInfo(){
System.out.println("This is grape");
}
}
print info of object:
Fruit f=new Grape();
f.printInfo();

Delegate method calling in Java

In Java: What is the best way to pass a method from one object to another so that it can be called at a later time by the second object?
I come from an ActionScript background where it is as easy to pass around references to methods as it is to pass around references to variables but this seems to be much more difficult in Java. The first few links I found flat out say it is not possible (and it may have been at the time of their posting), but then I found http://www.javacamp.org/javavscsharp/delegate.html which details how this can be accomplished.
My issue with using Javacamp's example is the string based reference to the method. Methods get renamed all the time and a string reference will only complain once you actually run that function runtime as opposed to compile time for a proper explicit link.
Is there no way to do this with proper explicit links to the method you want the other class to execute?
Model of what I am hoping to accomplish:
Player clicks an upgrade button on Activity1 > Activity1 passes upgrade method to a new confirmation activity
Player clicks "Yes" > Confirmation activity calls upgrade method passed in from Activity1
OR: Player clicks "No" > Confirmation Activity closes
EDIT:
To be clear I am not looking for a static method solution as that would require my Confirmation activity to hold many lines of logic for which static method to call. The Confirmation activity will be used all over my application: a simple "Are you sure you want to X?" -Yes -No, if yes execute X
I am currently looking at implementing onActivityResult to avoid this issue but that will be more logic than I like for this kind of issue.
you can use interfaces like this:
public interface MyMethod {
public void method();
}
public class FirtObject{
private SecondObject ob;
public void tellSecondObjectExecuteLater(){
ob.executeLater( new MyMethod() {
public void method(){System.out.println("duh Method");} });
}
}
public class SecondObject {
private MyMethod myMth;
public void executeLater(MyMethod mth){
myMth = mth;
}
public void executeNow(){
myMth.method();
}
}
does this solve your problem?
The typical way to pass methods is to use an Interface and Anonymous Inner Classes. In order to maintain static typing an Interface is used to declare the method signature and typing information. The caller can use either a concrete implementation of that interface as a normal class or using Anonymous Inner Classes for quick class creation. I'll use standard Java SDK classes to illustrate:
interface Comparator<T> {
public int compare( T a, T b);
}
class SpecialCollection<T> {
public void sort( Comparator<T> comparator ) {...}
}
public class SomeClient {
public void doSomething( SpecialCollection<SpecialObj> collection ) {
collection.sort( new Comparator<SpecialObj>() {
public int compare( SpecialObject a, SpecialObject b ) {
// some implementation
}
} );
}
}
The above is an example of a strategy pattern. The thing about the strategy pattern (and passing callback methods like in Javascript). The author has to plan for those types of extensions. The author has to predict up front where he/she wants you to extend. And it just happens it's cleanest if you use Interfaces.
However, pure delegation doesn't have to have always involve Interfaces. You can pass concrete classes, since Java can always pass a subclass that overrides various methods of that class to change what method or code will be invoked. For example in Java InputStream/OutputStream are abstract classes and you typically pass subclass instances to the methods.
If you need the method to act differently depending on the context (AKA, it is different depending on how it is created), you'll want to pass along the instance of the class that the method is in.
If it is a static method, you can just referenced the method itself if you import that class at the top of your new class.
For example, lets say you have a method that will tell you stuff about a certain string. IF the class looks like this:
class stringChecker {
private String stringToCheck;
public class stringChecker(String s) {
stringToCheck = s;
}
public int getStringLength() {
return stringToCheck.length();
}
public boolean stringStartsWith(String startsWith) {
return (stringToCheck.indexOf(startsWith) == 0);
}
}
Then you'll want to pass along the instance, since it is non-static. Different instances have different strings that they were created with, so you will get a different return if you use a different instance.
However, if your class looks more like this:
class stringChecker {
public static int getStringLength(String s) {
return s.length();
}
public static boolean stringStartsWith(String s, String startsWith) {
return (s.indexOf(startsWith) == 0);
}
}
Then you can just reference those methods with stringChecker.getStringLength("test");, because the methods are static. It doesn't matter what instance they are in. The returned result depends ONLY on what is being passed in. You just have to make sure to add import stringChecker; at the top or whatever your class will be called. For you, it'll probably be something like com.example.blah.otherthing.stringChecker, since you're working with android.
Good luck! I hope this helps :)
EDIT: Looks like I may have read the problem too quickly...if this isn't what you were asking about, just let me know with a comment and I'll delete this answer so as to not confuse anybody else.
You said that you are using it in a project to open a Confirmation activity.
Activities should not contain references to each other to avoid memory leaks. To pass data between activities should be used Intent class. To receive a result, call StartActivityForResult() and get result in the onActivityResult() method.
But in general for your task is more suitable AlertDialog or PopupWindow.

Combine advantages of clone and reference?

In Java, and maybe also in other languages, for example in a getter you have to decide if you want to return a reference to something or a clone (copy).
return myInstance;
Just returning the reference is very fast and needs no additional memory but modifications of an instance get "written back" the the original one.
return myInstance.clone();
Returning a clone needs time and doubles the memory for that variable but keeps it safe.
It is possible to create an immutable view on something:
return MyUtil.immutableView(myInstance);
but then sometimes I want to modify it, just not to have it written back.
Now my idea is, is it possible (or already done, or is there a programming language that does it) to create an object that is initially a reference to something as long as there are no modifications. As soon as the first modification begins, the reference would update itself to a clone.
Something like this:
Class<T> CloneReference
{
T ref;
boolean cloned=false;
public CloneReference(T ref) {this.ref=ref;}
T getForReadOnly()
{
return ref;
}
T getForReadWrite()
{
if(!cloned) ref=ref.clone();
return ref;
}
}
Unfortunately, this solution is complicated, clumsy and easy to break (calling getForReadOnly() and then using instance changing operations). Is it possible to do better or is that just not possible with Java?
What you're looking for sounds pretty much like Copy-On-Write. I remember that PHP is a language which did implement this.
I think it should basically be possible to implement COW in Java as well. I think of returning some proxy which is initialized with the original instance. On the first write access the proxy will continue using a copy. Here's a SSCCE:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
import static org.junit.Assert.*;
public class CowSSCCE {
public interface Bean {
public String getName();
public void setName(String name);
public Object clone();
}
public class BeanImpl implements Bean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() {
BeanImpl copy = new BeanImpl();
copy.name = new String(name);
return copy;
}
}
public class COWInvocationHandler implements InvocationHandler {
private Bean instance;
private boolean copy = false;
public COWInvocationHandler(Bean instance) {
this.instance = instance;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// copy only on the first setter call.
if (!copy && method.getName().startsWith("set")) {
instance = (Bean) instance.clone();
copy = true;
}
return method.invoke(instance, args);
}
}
#Test
public void testCOW() {
Bean original = new BeanImpl();
original.setName("original");
Bean reference = (Bean) Proxy.newProxyInstance(
Bean.class.getClassLoader(), new Class[] { Bean.class },
new COWInvocationHandler(original));
// no write access, reference is pointing to the original instance
assertEquals(original.getName(), reference.getName());
assertEquals(original.toString(), reference.toString());
// write access, reference is a copied instance
reference.setName("reference");
assertEquals("reference", reference.getName());
assertNotEquals(original.getName(), reference.getName());
assertNotEquals(original.toString(), reference.toString());
}
}
As someone mentioned readability, this shouldn't be an issue: Write an advice for e.g. the annotation #ReturnCopyOnwriteReference which replaces transparently the returned object with the proxy. An API method which returns such a proxy needs only that annotation:
#ReturnCopyOnwriteReference
public Bean getExpensiveBean() {
return originalBean;
}
If you're just looking for a COW collection use Java's CopyOnWriteArrayList.
Look at Scala programming language. It runs in JVM, and variables in most cases are immutable.
In Java there is a java.util.Collections#unmodifiableCollection() method, which wraps any collection into unmodifiable collection. This prevents it from editing. But I did not saw or think of any use case which would provide your desired behavior.
It sounds like you want something like C++'s const correctness. Unfortunately, there's nothing so innate in Java, but there are several strategies for achieving a similar result.
The whole point of any of these is to insure program correctness, and helping to reduce side effects.
Copy constructor
Always return a copy, that way the object inside the class is safe from modification. Implementing a copy constructor is probably the easiest, but you probably want a deep copy, which means any non-primitive members need to provide a way to obtain a deep copy of themselves (like another copy constructor).
Unmodifiable views
Java's Collections class does this with Collections.unmodifiableList, etc. This method accepts a List and proxies it with it's own (private) List implementation that forwards calls to accessor methods, but mutator methods throw an UnsupportedOpperationException. This is a little more dangerous because you can only support this with documentation.
Class hierarchy
You could always have a top level interface Foo which is unmodifiable, and an interface ModifiableFoo, where necessary you only return the former. Probably the best option since you can enforce mutability with the compiler and not runtime exceptions, as above.
I wrote about this subject once in my blog:
http://eyalsch.wordpress.com/2010/02/11/refdamage/
In general, I try to follow the following principles, with respect to the "main" object and the reference that "escapes" from it (either as a parameter or a returned value):
1) If the main object exposes some reference, we must make sure that the reference can't be manipulated in such a way that the class is left in an inconsistent state. This can be done in many ways (defensive copies, immutability, listeners, etc..).
2) In case that modifications to the reference's state are legal and are automatically reflected in the main object state, this must be properly documented.
3) If the caller wishes to update the reference state without affecting the main object, it's the caller's responsibility to clone properly.

how to unit test a class which creates new objects

I'm using JUnit and Mockito to test some classes. The class itself creates an object from another class. A list called testList. Here my code:
public class A {
private List<B> bList;
//returns the bList
public List<B> getBList() {
return bList;
}
//checks the status by calling getStatus in class B
public Status getStatus() {
//status is an enum consists of PASSED and FAILED
Status finalStatus = Status.PASSED;
for (B be : this.getTestList()) {
if (be.getStatus() != Status.PASSED) {
finalStatus = Status.FAILED;
break;
}
}
return status;
}
}
public Class B {
private Status status = Status.FAILED;
public getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
What would be the best way to test the getStatus and getTestList methods in the class called Test.
Thank you very much....
I looked at your ClassA and I wondered how bList ever gets set to anything. Right now, there's no way for it to be anything other than null, which means that getStatus will throw a null pointer exception every time.
Your problem is that you are thinking about how to test methods instead of thinking about how to test behaviour. One reason why this is a problem is that your class has to fit in with the rest of your application in a certain way. To be sure that it does that, it needs certain behaviour, not certain details within each method. So the only meaningful test is one that checks the behaviour.
Perhaps more insidious is the fact that testing individual methods makes you focus on the code that you have in fact written. If you are looking at your code while you write your test, then your test becomes a self-fulfilling prophecy. You may have missed a whole set of behaviour that your class is required to provide; but if you only test the behaviour that your class does provide, you'll never know.
So, back to the problem in hand. I see four, maybe five behaviours that your class might be expected to fulfil. Maybe there are more - it's hard to tell if you only show us the code, and not the specification. You should write a test for each one. I strongly believe that the name of each test should describe the behaviour, rather than reflecting the name of the methods that the test uses. In this case, I might choose names like this.
public void statusIsPassedWhenEveryTestPassed()
public void statusIsFailedWhenEveryTestFailed()
public void statusIsFailedWhenSomeTestsPassedSomeFailed()
public void statusIsPassedWhenNoTests()
public void statusIsPassedWhenTestsNotSet() // this one currently fails
Within each test, I would create an object of ClassA, then do whatever has to be done to set the bList within the object. Lastly, I would call getStatus and assert that the return value is what I want. But the important point is that each test (except the last one) uses more than one method of ClassA, so these are not tests of an individual method.
You can provide setters (or constructor injection) for the objects in question as protected and then extend the class inside your test case to mock the objects or you can try using something like powermock. You would still need to provide a way to set those objects in question.
I guess it depends on how you can populate testList in a unit test. If you have, say, a setter, then you would not need any mocking frameworks
class TestTest {
Test test = new Test();
#Test void should_return_failed_if_a_single_test_failed() {
givenTestListWithOneFailedTest();
assertThat(test.getStatus(), is(Status.FAILED))
}
void givenTestListWithOneFailedTest() {
test.setTestList(createSomeTestListWithOnlyOneFailedTest());
}
#Test void should_return_passed_if_all_tests_passed() {
// ...
}
}

Is it possible to do computation before super() in the constructor?

Given that I have a class Base that has a single argument constructor with a TextBox object as it's argument. If I have a class Simple of the following form:
public class Simple extends Base {
public Simple(){
TextBox t = new TextBox();
super(t);
//wouldn't it be nice if I could do things with t down here?
}
}
I will get a error telling me that the call to super must be the first call in a constructor. However, oddly enough, I can do this.
public class Simple extends Base {
public Simple(){
super(new TextBox());
}
}
Why is it that this is permited, but the first example is not? I can understand needing to setup the subclass first, and perhaps not allowing object variables to be instantiated before the super-constructor is called. But t is clearly a method (local) variable, so why not allow it?
Is there a way to get around this limitation? Is there a good and safe way to hold variables to things you might construct BEFORE calling super but AFTER you have entered the constructor? Or, more generically, allowing for computation to be done before super is actually called, but within the constructor?
Thank you.
Yes, there is a workaround for your simple case. You can create a private constructor that takes TextBox as an argument and call that from your public constructor.
public class Simple extends Base {
private Simple(TextBox t) {
super(t);
// continue doing stuff with t here
}
public Simple() {
this(new TextBox());
}
}
For more complicated stuff, you need to use a factory or a static factory method.
I had the same problem with computation before super call. Sometimes you want to check some conditions before calling super(). For example, you have a class that uses a lot of resources when created. the sub-class wants some extra data and might want to check them first, before calling the super-constructor. There is a simple way around this problem. might look a bit strange, but it works well:
Use a private static method inside your class that returns the argument of the super-constructor and make your checks inside:
public class Simple extends Base {
public Simple(){
super(createTextBox());
}
private static TextBox createTextBox() {
TextBox t = new TextBox();
t.doSomething();
// ... or more
return t;
}
}
It is required by the language in order to ensure that the superclass is reliably constructed first. In particular, "If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass."
In your example, the superclass may rely on the state of t at construction time. You can always ask for a copy later.
There's an extensive discussion here and here.
You can define a static supplier lambda which can contain more complicated logic.
public class MyClass {
private static Supplier<MyType> myTypeSupplier = () -> {
return new MyType();
};
public MyClass() {
super(clientConfig, myTypeSupplier.get());
}
}
The reason why the second example is allowed but not the first is most likely to keep the language tidy and not introduce strange rules.
Allowing any code to run before super has been called would be dangerous since you might mess with things that should have been initialized but still haven't been. Basically, I guess you can do quite a lot of things in the call to super itself (e.g. call a static method for calculating some stuff that needs to go to the constructor), but you'll never be able to use anything from the not-yet-completely-constructed object which is a good thing.
This is my solution that allows to create additional object, modify it without creating extra classes, fields, methods etc.
class TextBox {
}
class Base {
public Base(TextBox textBox) {
}
}
public class Simple extends Base {
public Simple() {
super(((Supplier<TextBox>) () -> {
var textBox = new TextBox();
//some logic with text box
return textBox;
}).get());
}
}
That's how Java works :-) There are technical reasons why it was chosen this way. It might indeed be odd that you can not do computations on locals before calling super, but in Java the object must first be allocated and thus it needs to go all the way up to Object so that all fields are correctly initialized before you can modify them.
In your case there is most of the time a getter that allows you to access the parameter you gave to super(). So you would use this:
super( new TextBox() );
final TextBox box = getWidget();
... do your thing...

Categories

Resources