I want to mock a class using the Mockito framework, that has a couple of constructor arguments.
How would i go about passing those constructor arguments without generating setters for the private member variables ?
Thanks
You said you want to mock some but not all of the methods. I'm not sure why you'd want to do this - if your class is a collaborator, then it would make sense to mock the whole class. Or if it's the SUT, you probably don't want to mock it at all.
It's possible that what you're looking for is a spy, rather than a mock. If you decide to use a spy, you'll make it from a real object, which has already been constructed using whatever arguments you need it to be constructed from.
But before you consider using a spy, I urge you to think more carefully about exactly what it is that you're testing, and why you think you need to replace some of your methods with mock implementations, but not others.
Related
I'm writing a JUnit test for a method containing the following:
if (p.toString().contains("abc")) {
cCreds(p);
refMgr();
p = new Path(Utils.rmvTkn(p.toString()));
}
cCreds(p); and refMgr(); call void methods. I'm not actually testing these methods but they do get called in the method I am testing so I have to deal with them in some way. I know I need some sort of test double but I'm not sure what. I assume its not with a when().thenReturn(); as nothing is actually returned.
Can anybody advise?
Edit
I should also mention, cCreds(p); and refMgr(); are also private.
Mocking is not necessary the thing to do here.
As these methods :
cCreds(p);
refMgr();
make part of the class under test, you are not compelled to mock them.
Mocking public or private methods of the class under test is not very natural.
It makes generally tests more brittle and less clear.
Mockito provides spy concept to achieve it but it should be favored for legacy code.
In the actual implementation, what you should check is that the method returns or performs a side effect which is expected.
You don't show the whole code of the method, so it is hard to give a more specific pointer.
Note that if these methods :
cCreds(p);
refMgr();
rely some other classes that you need to mock to isolate the component under test, you could refactor your code to extract the method in the dependent classes.
You would invoke them in this way :
foo.cCreds(p);
bar.refMgr();
And you could so mock them easily.
Use doNothing() API from Mockito to mock void methods
doNothing().when(mock).cCreds(p);
doNothing().when(mock).refMgr();
Source: http://www.baeldung.com/mockito-void-methods
I am writing test cases for a liferay portal in which I want to mock ActionRequest, ThemeDisplay kind of objects. I have tried with writing expectations in each test method.
Now I want to generalize the approach by creating a BaseTest class which provides me all expectations needed for each method so that I don't have to write it again in the all test classes.
For one class I have tried by writing expectations in #Before method. How can I use same in different classes?
For example I want to do following in several classes:
#Before
public void setUp() {
// All expectations which are required by each test methods
new Expectations() {{
themeDisplay.getPermissionChecker();
returns(permissionChecker);
actionRequest.getParameter("userId");
returns("111");
actionRequest.getParameter("userName");
returns("User1");
}};
}
Also is there a way to provide that whenever I call actionRequest.getParameter() it may return the specific value which I provide?
Any help will be appreciated.
Generally, what you want is to create named Expectations and Verifications subclasses to be reused from multiple test classes. Examples can be found in the documentation.
Note that mocked instances have to be passed in, when instantiating said subclasses.
Methods like getPermissionChecker(), however, usually don't need to be explicitly recorded, since a cascaded instance is going to be automatically returned as needed.
Mocking methods like getParameter, though, hints that perhaps it would be better to use real objects rather than mocks. Mocking isn't really meant for simple "getters", and this often indicates that you may be mocking too much.
I need to write unit tests with Java for an Android application. What I currently need to do is to create an object Picture and use it for some tests. The problem with this object is, that it's constructor has a method call:
public Picture(File imageFile) {
this.filename = imageFile.getName();
this.imageDimension = getImageDimension();
/.../
}
Method getImageDimension() references some other classes, therefore I would prefer for separability to just mock it's result. For mocking, I need to give Mockito a constructor, so it seems to me like a chicken-egg problem.
So, is there a chance to mock a function used in the object constructor with Mockito? If no, how could this situation be solved without changing the original code?
Normally you'd mock the entire object and not just a part of it. But if it's not final, create a subclass of Picture and override the constructor and do your custom thing there. That way you can avoid calling the original constructor and you can test the instance.
If it is final then unit testing it becomes quite hard. If you are not actually unit testing this particular class, you should either mock the picture object entirely or not at all.
BTW, this is why you shouldn't allow your constructors to do work: it results in code that is hard to test & mock. Separating object initializations from your logic is a good thing. Probably what you'd want here is an additional constructor that takes filename and dimensions as constructor args.
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.
I have a hibernate POJO that I want to unit test. It looks similar to this:
public class MyPojo{
private final Integer someIntData;
private MyPojo(){
//Just to satisfy compiler, hibernate will override
someIntData = null;
}
//Methods etc...
}
I'd like to unit test this class, but don't really want to make a new constructor just to set 'someIntData' manually. Is there a quick and easy way to get hibernate to instantiate a test instance of MyPojo without mucking around with a mock database?
Private constructor means that you are either providing a "builder" method to replace the constructor (usually for immutable instances) or that the class is never meant to be initialized at all. In the later case, its usually because the class is meant to be a singleton and you'd provide a method which returns the single instance.
Hibernate does not complain about it because it uses reflection to consume this constructor. As you are not supposed to provide special code for a test, the only solution I see is to use reflection to instantiate a new POJO.
But I really think you should reconsider and provide a builder method, accepting the parameters needed to build a new instance.
What I'm going to suggest is ugly, but I think the best approach is not to use hibernate for the unit test, and use reflection to instantiate the object (which is what hibernate does internally). For example
Constructor[] cons = MyPojo.class.getDeclaredConstructors();
// Change the accessible property of the constructor.
cons[0].setAccessible(true);
MyPojo secret = (MyPojo)cons[0].newInstance(null);
Code taken from http://dunwood.blogspot.com/2004/05/instantiate-java-class-that-has.html
I remember reading that there are some frameworks that make using reflection easier for unit-tests, but I've never used them. In this type of cases, I always prefer to create a second constructor or to make the constructor package protected.
If it's a real unit test, you shouldn't need to depend on Hibernate.
It's common to change the visibility of methods, or even introduce some in order to be able to unit test a class. I wouldn't mind having a public constructor with an Integer as argument in order to unit test the POJO.
You'll certainly need to be able to set the ID in your POJOs when you'll test services anyway. For example, if you want to test that myService(MyPOJO p)calls myDAO.findFoos(p.getId()), you'll need an ID in your POJO.