Mock a superclass constructor - java

I would like to know if I can mock a super class constructors call and its super() calls.
For example, I have the following classes
class A
{
A(..)
{
super(..)
}
}
class B extends A
{
B(C c)
{
super(c)
}
}
So, I am planning to unit test some methods in class B, but when creating an instance it does call the super class constructors making it tough to write unit tests. So, how can I mock all the super class constructor calls. Also I would like to mock few methods in class A so that it does return few values as I need.
Thanks!!

You could use PowerMock library. It is really a lifesaver when you need to accomplish things like yours.
https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior

Mocking a constructor is a very bad idea. Doing so is circumventing behavior that will happen in production. This is why doing work in the constructor, such as starting threads and invoking external dependencies, is a design flaw.
Can you honestly say that the work performed in the constructor has no effect on the behavior you're trying to test? If the answer is no, you run the risk of writing a test that will pass in a test environment, but fail in production. If the answer is yes, that is a plain case for moving that "work" outside the constructor. Another alternative is to move the behavior you're trying to test to another class (maybe it's own).
This is even more true if you're using a DI framework like Guice (which I assume because you tagged it that way).

The short answer to your question is "not exactly." You can't 'mock' a constructor, let alone a super. Also mocking super.anyMethod is difficult or impossible with mocking frameworks I'm familiar with. Powermock does allow you to suppress super constructors and problematic methods, which isn't quite the same as mocking them, but could help.
When B extends A, it is of course completely coupled with A. That's not a problem per se but it can be and it looks like it is here. Instead of having B extend A, try having B contain an A instead (and perhaps implement the same interface if necessary). Then you can inject a mock A and delegate all of the calls that you want. That would be much easier to unit test, no?
It's one of the benefits of test driven development that you discover these things in your design during testing.

Related

What should be checked in junit for a method that simply calls super.method()?

I have a junit method that only calls super.method(). What should be asserted in the junit for this method.
public String foo()
{
return super.foo();
}
Is asserting that the super.foo() is getting called enough.
Or, I should compare the values as well.
This is an interesting question and I doubt can be answered without more context and understanding of the importance of this code.
If you want to favor isolated tests then I would say there is little to test here. Instead, I would ensure that super.foo() was well tested in the test class for the superclass. The advantage of this approach means that if the superclass' behavior changes the unit tests only need updating in one place.
However, if there is a strong business reason for this behavior then it could make sense to test that the implementation here as well. With careful reuse of code in the unit tests, it would minimize the maintenance headache moving forward.
Essentially the choice of what and how to test this method comes down to a balance between completeness of coverage and cost of ongoing maintenance.
If calling the super method is the only thing this method does, you don't have to create the method in the first place.
Whatever class this is inherits all methods of the super class, meaning you can call foo() without overriding it.
If it's not the only thing it does, you can assert the same stuff you assert in the junit test for the super method.
Don't test the implementation: test the behaviour. ie, when you call the foo() method, does it do what it's supposed to do?
Unless calling super.foo() is part of the contract of the sub-class foo() method, which is almost a code smell, but there are test frameworks that can specifically assert if certain methods are called. Spock is my favorite (not sure of the syntax, because I've never had to assert calls to super... furher evidence, albeit anecdotal, of code smell. If you method only calls super.foo(), delete it and let type hierarchy do it for you.

Unit test for method that calls multiple other methods using Mockito

Perhaps I have completely fallen short in my search, but I cannot locate any documentation or discussions related to how to write a unit test for a Java class/method that in turn calls other non-private methods. Seemingly, Mockito takes the position that there is perhaps something wrong with the design (not truly OO) if a spy has to be used in order to test a method where mocking internal method calls is necessary. I'm not certain this is always true. But using a spy seems to be the only way to accomplish this. For example, why could you not have a "wrapper" style method that in turn relies on other methods for primitive functionality but additionally provides functionality, error handling, logging, or different branches dependent on results of the other methods, etc.?
So my question is two-fold:
Is it poorly designed and implemented code to have a method that internally calls other methods?
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
This might be a difficult request, but I would prefer for those who decide to answer to not merely re-publish the Mockito verbiage and/or stance on spies as I already am aware of that approach and ideology. Also, I've used Powermockito as well. To me, the issue here is that Mockito developed this framework where additional workarounds had to be created to support this need. So I suppose the question I am wanting an answer to is if spies are "bad", and Powermockito were not available, how is one supposed to unit test a method that calls other non-private methods?
Is it poorly designed and implemented code to have a method that internally calls other methods?
Not really. But I'd say that, in this situation, the method that calls the others should be tested as if the others where not already tested separately.
That is, it protects you from situations where your public methods stops calling the other ones without you noticing it.
Yes, it makes for (sometimes) a lot of test code. I believe that this is the point: the pain in writing the tests is a good clue that you might want to consider extracting those sub-methods into a separate class.
If I can live with those tests, then I consider that the sub-methods are not to be extracted yet.
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
I'd do something like that:
public class Blah {
public int publicMethod() {
return innerMethod();
}
int innerMethod() {
return 0;
}
}
public class BlahTest {
#Test
public void blah() throws Exception {
Blah spy = spy(new Blah());
doReturn(1).when(spy).innerMethod();
assertThat(spy.publicMethod()).isEqualTo(1);
}
}
To me, this question relates strongly to the concept of cohesion.
My answer would be:
It is ok to have methods (public) that call other methods (private) in a class, in fact very often that is what I think of as good code. There is a caveat to this however in that your class should still be strongly cohesive. To me that means the 'state' of your class should be well defined, and the methods (think behaviours) of your class should be involved in changing your classes state in predictable ways.
Is this the case with what you are trying to test? If not, you may be looking at one class when you should be looking at two (or more).
What are the state variables of the class you're trying to test?
You might find that after considering the answers to these types of questions, your code becomes much easier to test in the way you think it should be.
If you really need (or want) to avoid calling the lower-level methods again, you can stub them out instead of mocking them. For example, if method A calls B and C, you can do this:
MyClass classUnderTest = new MyClass() {
#Override
public boolean B() {return true;}
#Override
public int C() {return 0;}
};
doOtherCommonSetUp(classUnderTest);
String result = classUnderTest.A("whatever");
assertEquals("whatIWant", result);
I've used this quite a quite a bit with legacy code where extensive refactoring could easily lead to the software version of shipwright's disease: Isolate something difficult to test into a small method, and then stub that out.
But if the methods being called are fairly innocuous and don't requiring mocking, I just let them be called again without worrying that I am covering every path within them.
The real question should be:
What do I really want to test?
And actually the answer should be:
The behaviour of my object in response to outside changes
That is, depending on the way one can interact with your object, you want to test every possible single scenario in a single test. This way, you can make sure that your class reacts according to your expectations depending on the scenario you're providing your test with.
Is it poorly designed and implemented code to have a method that internally calls other methods?
Not really, and really not! These so called private methods that are called from public members are namely helper methods. It is totally correct to have helper methods!
Helper methods are there to help break some more complex behaviours into smaller pieces of reusable code from within the class itself. Only it knows how it should behave and return the state accordingly through the public members of your class.
It is unrare to see a class with helper methods and normally they are necessary to adopt an internal behaviour for which the class shouldn't react from the outside world.
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
In my humble opinion, you don't test those methods. They get tested when the public members are tested through the state that you expect out of your object upon a public member call. For example, using the MVP pattern, if you want to test user authentication, you shall not test every private methods, since private methods might as well call other public methods from an object on which depend the object under test and so forth. Instead, testing your view:
#TestFixture
public class TestView {
#Test
public void test() {
// arrange
string expected = "Invalid login or password";
string login = "SomeLogin";
string password = "SomePassword";
// act
viewUnderTest.Connect(login, password);
string actual = viewUnderTest.getErrorMessage;
// assert
assertEqual(expected, actual);
}
}
This test method describes the expected behaviour of your view once the, let's say, connectButton is clicked. If the ErrorMessage property doesn't contain the expected value, this means that either your view or presenter doesn't behave as expected. You might check whether the presenter subscribed to your view's Connect event, or if your presenter sets the right error message, etc.
The fact is that you never need to test whatever is going on in your private methods, as you shall adjust and bring corrections on debug, which in turn causes you to test the behaviour of your internal methods simultaneously, but no special test method should be written expressly for those helper method.

Mocking a class vs. mocking its interface

For a unit test, I need to mock several dependencies. One of the dependencies is a class which implements an interface:
public class DataAccessImpl implements DataAccess {
...
}
I need to set up a mock object of this class which returns some specified values when provided with some specified parameters.
Now, what I'm not sure of, is if it's better to mock the interface or the class, i.e.
DataAccess client = mock(DataAccess.class);
vs.
DataAccess client = mock(DataAccessImpl.class);
Does it make any difference in regard to testing? What would be the preferred approach?
It may not make much difference in your case but the preferred approach is to mock interface, as normally if you follow TDD (Test Driven Development) then you could write your unit tests even before you write your implementation classes. Thus even if you did not have concrete class DataAccessImpl, you could still write unit tests using your interface DataAccess.
Moreover mocking frameworks have limitations in mocking classes, and some frameworks only mock interfaces by default.
In most cases technically there is no difference and you may mock as class so an interface. Conceptually it is better to use interfaces because of better abstraction.
It depends. If your code depends on the class and not on the interface you must mock the class to write a valid unit test.
You should mock the interface since it will help ensure you are adhering to Liskov Substitution Principal (https://stackoverflow.com/a/56904/3571100).
If you only use it through interface and it's not a partial mock, there is no difference other than your inner feeling. Mocking the class will also mock non-used public method if the class has them, but that is not a big deal to consider.

How to mock parts of a service and test others?

I'm using easymock, and I am mocking my UserService class.
My UserService has a few methods:
boolean canUserLogin(..);
boolean canUserJoinClass(...);
Now some of the methods call each other, and if I am testing method#1 I want to stub/mock methods #2 and methods# 3 that are called in method#1.
What I am confused is, how can I mock parts of a class and leave others to run the actual code?
So I want to actually test UserService.method#1, but mock UserService.method#2 and UserService.method#3 that method#1 calls internally.
By specifying return values for the methods you want mocked; see the easymock docs for examples.
The "Specifying Return Values" section discusses creating return values for mocked methods.
The "Partial mocking" section (towards the bottom) discusses mocking actual classes.
I agree with the docs (and other answers) that this may be an indication of sketchy design. Without further details, it's hard to say how sketchy it is, if it is at all.
You can check some library like Easymock, but I don't sure whether it can do this.
And here is my solution without third-party library. Create a subclass of UserService, and override the method you want to mock.
class SubUserService{
#override
boolean canUserJoinClass(...){
return false;
}
}
But notice the mock method can't be private.
And if this is one real problem you meet, you should refactor you methods to different classes.
I know Mockito supports "spy" on real objects. I could not find an equivalent in Easy Mock. So, I am not sure if you can do this.
Having said that, this is a smell to me. Why do you need to mock it? Is that an indication of the fact that your object is doing too much and hence you need to mock the other interactions?
Also, whenever you need to worry about the implementation of a method (method 1 in this case) i.e. the fact that it calls method2 and method3, especially of the same class, that sounds to me like a encapsulation leaking.
Mocking is intended to be used for dependencies, so you can test in isolation. In this case, you don't have any dependencies, since the methods you are calling are on one class. So I wouldn't use mocking here.
If methods 2 and 3 are so complicated that you want to mock them when testing method 1, then perhaps you should separate them out into their own class(es), so you can easily mock them.

junit & java : testing non-public methods [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
JUnit will only test those methods in my class that are public. How do I do junit testing on the ones that are not (i.e., private, protected)?
I can test them by not using junit, but I was wondering what the junit standard method was.
One school of thought about unit testing says that you should only be able to test public methods, because you should only be unit-testing your public API, and that by doing so, you should be covering the code in your non-public methods. Your mileage may vary; I find that this is sometimes the case and sometimes not.
With that said, there are a couple of ways to test non-public methods:
You can test protected and package-scope methods by putting your unit tests in the same package as the classes they're testing. This is a fairly common practice.
You can test protected methods from unit tests in another package by creating a subclass of the class under test that overrides the methods you want to test as public, and having those overridden methods call the original methods with the super keyword. Typically, this "testing subclass" would be an inner class in the JUnit TestCase class doing the testing. This is a little bit more hacky, in my opinion, but I've done it.
As with many unit testing problems, testing private methods is actually a design problem in disguise. Rather than try to do anything tricky to test private methods, when I find myself wishing to write tests for private methods I take a minute to ask myself, "How would I need to design this so I could test it thoroughly through public methods?"
If that doesn't work, JUnitX allows testing private methods, although I believe it is only available for JUnit 3.8.
When you write a JUnit test, you have to do a subtle mind shift: "I'm a client of my own class now." That means private is private, and you only test the behavior that the client sees.
If the method really should be private, I'd consider it a design flaw to make it visible just for the sake of testing. You've got to be able to infer its correct operation based on what the client sees.
In the three years that have passed since I originally wrote this, I've started approaching the problem slightly differently, using Java reflection.
The dirty little secret is that you can test private methods in JUnit just as you would public ones, using reflection. You can test to your heart's content and still not expose them as public to clients.
The simplest solution is to put the JUnit tests in the same package (but different directory) and use default (i.e. package-private) visibility for the methods.
Another more complicated approach is to use reflection to access private methods.
If you have a significant amount of logic buried under relatively few "Public" entry points, you are probably violating the Single Responsibility Principle. If possible, you'll want to refactor the code into multiple classes, ultimately leading to more "Public" methods from which to test.
Here is the "probably shouldn't do it this way" method that everyone else keeps harping at you about. I think it's certainly within the realm of possibility that there are reasons for doing it this way, though. The following code will access a private field, but the code for a private method is nearly identical.
public void testPrivateField() throws InterruptedException {
Class<ClassWPrivateField> clazz = ClassWPrivateField.class;
try {
Field privateField = clazz.getDeclaredField("nameOfPrivateField");
privateField.setAccessible(true); // This is the line
// do stuff
} catch(NoSuchFieldException nsfe) {
nsfe.printStackTrace();
fail();
} catch(IllegalAccessException iae) {
iae.printStackTrace();
fail();
}
}
I've come across the same issue, and the "if it needs to be private it probably should be refactored" doesn't sit right with me.
Suppose you have sort of functionality that you want to separate out in some way internal to the class. For example, suppose I have something like this:
public class HolderOfSomeStrings{
private List<String> internal_values;
public List<String> get()
{
List<String> out = new ArrayList<String>();
for (String s:internal_values)
{
out.add(process(s));
}
return get;
}
private static String process(String input)
{
//do something complicated here that other classes shouldn't be interested in
}
}
The point here is that junit forces me to make process public, or at least protected, or to put it in it's own utility class. But if it's some sort of internal logic of HolderOfSomeStrings, it's not at all clear to me that this is correct—it seems to me that this ought to be private, and making it more visible gums up the code in some way.
I nearly always use Spring in my Java projects and, as such, my objects are built for dependency injection. They tend to be fairly granular implementations of public interfaces that are assembled within the application context. As such, I rarely (if ever) have the need to test private methods because the class itself is small enough that it simply isn't an issue.
Even when I don't use Spring I tend to adopt the same practices of assembling small and simple objects into larger and larger abstractions, each of which is relatively simple but made complex by the aggregated objects.
In my experience, having the need to unit test private methods is an indicator that what you're teesting could (and should) be simplified.
That being, if you still really feel the need:
Protected methods can be tested by subclasses;
Package private methods can be tested by putting the unit tests in the same package; and
Private methods can be unit tested by providing, for example, a package private factory proxy method. Not ideal but private does mean private.
You usually don't test private methods because they can only (normally) be tested indirectly through another public method. When you're test driving and make private methods then they are usually a result of an "extract method" refactoring and are already by then tested indirectly.
If you are concerned about testing a private method with lots of logic then the smartest thing you could do is to move that code into another class in a public method. Once you've done that, the previous method that used this code can have it's testing simplified by having the functionality provided by a stub or a mock.
To borrow a thought from Andy Hunt, even your private methods must have some side effect that you're interested in. In other words, they must be called from some public method and perform an interesting task that causes the state of your object to change. Test for that state change.
Suppose you have public method pubMethod and private method privMethod. When you call pubMethod, it in turn calls privMethod to perform a task (perhaps parsing a String). The pubMethod then uses this parsed String to set member variables' values in some way or to influence its own return value. Test by watching for the desired effect on pubMethod's return value or on member variables (possibly by using accessors to get to them).
DP4j Jar
For testing private methods we need to use reflection and its pointed in all answers.
well now this task is simplified with help of Dp4j jar.
Dp4j analyzes your code and automatically generates the Reflection API code for you.
Just add dp4j.jar to your CLASSPATH.
Dp4j.jar contains Annotation Processors, they will look for the methods in your code that are annotated with #Test JUnit annotation.
Dp4j analyze the code of those methods, and if it finds that you are illegally accessing private methods, it will replace your invalid private method reference with equivalent code that uses Java's Reflection API.
Get More details here
You can use TestNG instead of JUnit, which doesn't care about the method being private or public.
Use reflection as above to test private methods.
If we are following TDD we should test private methods given that TDD implies that there would be no surprises later.
So one should not wait to finish his public method to test privates.
And this helps in more granular regression testing upon re factoring.
Look for "PrivateAccessor.invoke". My code imports it from "junitx.util", but I don't know where it came from.
In agreement with just about every post--you should probably refactor and probably not test private except through public, just wanted to add a different way to think about it...
Think of your class itself as a "Unit", not a method. You are testing the class and that it can maintain a valid state regardless of how it's public methods are called.
Calling private methods can destroy the encapsulation and actually invalidate the tests.
As kind of an offshoot of this, and I'm not sure where everyone comes down on the whole "polyglot programming" issue, but Groovy tests are runnable in Junit, and ignore the whole public/non-public issue. Side note, it was officially classified as a "bug", but when they tried to fix it, there was such a storm kicked up about it that it was put back as it was originally.
I absolutely agree with #duffymo that code should be tested from the client's view ( though he says he quit thinking this way). However, from this point of view, private vs others have different meanings. Client of a private method is the class itself so I prefer testing them through the external (public/package-protected) API. However, protected and package-protected members are there for external clients, so I test them with fakes which inherit the owning class or which reside in the same package.

Categories

Resources