Unable to mock object of class residing in different project - java

This is how I am mocking object of class Client present in another project:
#Mock
private Client client;
//Mocking method of class client -
#Test
public void test()
{
Mockito.when(client.getPassportDetail(Matchers.eq(bytes),Matchers.eq(properties)))
.thenReturn(hash);
}
Structure of class Client:
class Client
{
public static boolean loadLibraries(Properties properties) {
}
public HashMap<String, String> getPassportDetail(byte[] b, Properties properties) throws Exception{
if (!loadLibraries(properties))
{
throw new UnsatisfiedLinkError();
}
}
So, when I mock getPassportDetail method, it gets called, not mocked.

That's a common mistake. Actually #Mock annotation need something more to work as You want to.
You have 3 options there:
Add
#RunWith(MockitoJUnitRunner.class)
to Your test class.
Or
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
There is also 3rd option, that #Dawood ibn Kareem suggest in comment below:
There's a third option, which is better than either of these two. Use the new Mockito Rule - #Rule public MockitoRule rule = MockitoJUnit.rule();. More detail at my answer here, which also explains why this is the best of the three options.
That should be all.
You can always refer to http://www.baeldung.com/mockito-annotations for more informations and detailed explanation.

Related

Unit testing a method of a class that has a constructor and an autowired field that needs to be mocked using mockito

I have a service class that extends another service with a constructor. This class has an autowired field and a method that I wanted to unit test using Mockito. However, I am having trouble writing a unit for it.
Let say the service looks somewhat like this:
#Service
public class SomeService extends Service {
#Autowired
private SomeClient someClient;
public SomeService(Product product, #Qualifier(Constants.SOME_BEAN) Details temp) {
super(product, temp);
}
#Override
public State create() {
Request request = new Request();
request.set...
request.set..
Status status = someClient.createTenant(request);
..
.. // construct a State object and return
}
}
Now, I am writing a test for this class and I am trying to unit test the method create() above. I am having trouble mocking someClient there when this method is called by my test.
The test class looks somewhat like:
#RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
private Detail temp;
private SomeFacade service;
private SomeClient someClient;
private Product product;
#Before
public void setup() {
temp = mock(Details.class);
product = mock(Product.class);
service = spy(new SomeService(product, temp));
someClient = mock(SomeClient.class);
}
#Test
public void test() {
Status status = new Status();
status.setStatus(...);
when(someClient.createTenant(any())).thenReturn(status);
State state = service.create();
// asserts
}
}
What I want to is that when I call service.create in the test above, the call
someClient.createTenant(request); in the method tested should be mocked to return a value and this is something I am not able to get working. Any help?
We can use Mockito's #InjectMocks-annotation to inject mocks into our unit under test. For this, we also need to
remove mock intialization from the setup()-method and
annotate the mocks with #Mock
Remarks:
Instead of field injection, I would recommend constructor injection. This allows, among other things, to keep the structure of the code and create the unit under test within setup() by manual injection
I would also recommend to add a type to the when: when(someClient.createTennant(any(Request.class)))...
As was pointed out by #second, the spy on the unit under test is superfluous.
Also pointed out by #second was the fact that field injection will not work if a constructor is present

How to write non-encapsulated unit tests?

I have an autowired variable
#Autowired
private DocumentConfig documentConfig;
I want to make tests for the DocumentService with various states of this configuration object. What are my options? What is the best option?
The first idea is this:
#Test
public void save_failure() {
documentConfig.setNameRequired(true);
/*
testing code goes here
*/
documentConfig.setNameRequired(false);
}
But I want to be somewhat more sure that the variable is reset after the test to not interfere with the other tests, to make sure only this test gets an error if it's the source of a problem.
My new idea was this:
#Before
public void after() { documentConfig.setNameRequired(true); }
#Test
public void save_failure() {
/*
testing code goes here
*/
}
#After
public void after() { documentConfig.setNameRequired(false); }
However, this doesn't work at all because Before and After execute for the whole file and not this single test. I would prefer not to make a new file just for one test.
I've now settled on a compromise:
#Test
public void save_failure() {
documentConfig.setNameRequired(true);
/*
testing code goes here
*/
}
#After
public void after() { documentConfig.setNameRequired(false); }
It seems to do everything I want but I have a few questions.
Assuming nameRequired starts as false, is this guaranteed not to interfere with the other tests?
Is there any way I can make this more clear? Both for my future self and for others.
You can create it before each test. Smth like
private DocumentConfig documentConfig;
#Before
public void createConfig() {
documentConfig = new DocumentConfig(mockedParams);
}
An often used approach is to set up a dummy DocumentConfig and inject it within the setUp() method (annotated with #Before) so that the entire context is reset within each test, for example:
#Before
public void setUp() {
this.documentConfig = new DocumentConfig();
this.documentConfig.setNameRequired(false);
this.service = new DocumentService(this.documentConfig);
}
In this case, I've set up a simple object with nameRequired being false. I could probably delete that statement, because a boolean field defaults to false anyways.
If you don't use constructor injection, and you don't have a setter for documentConfig, you'll have to use reflection to inject the field, for example:
ReflectionTestUtils.setField(this.service, "documentConfig", this.documentConfig);
Within your test you could now write something like this:
#Test
public void save_failure() {
this.documentConfig.setNameRequired(true);
// TODO: Implement test
}
Alternatively, you could mock DocumentConfig, so that you don't rely on its implementation to test DocumentService. I assume that you're calling isNameRequired() somewhere in the code of DocumentService, so you could mock it like this:
#Before
public void setUp() {
// Use a static import for Mockito.mock()
this.documentConfig = mock(DocumentConfig.class);
this.service = new DocumentService(this.documentConfig);
}
#Test
public void save_failure() {
// Use a static import for Mockito.when()
when(this.documentConfig.isNameRequired()).thenReturn(true);
// TODO: Implement test
}
Since this mocking/injection setup happens quite often, Mockito also has its own runner that allows you to get rid of the setUp() method, for example:
#RunWith(MockitoJUnitRunner.class)
public class DocumentServiceTest {
#InjectMocks
private DocumentService documentService;
#Mock
private DocumentConfig documentConfig;
#Test
public void save_failure() {
when(this.documentConfig.isNameRequired()).thenReturn(true);
// TODO: Implement test
}
}
It is not yet clear, which testing framework you use. For plain unit tests, make the value injectable by either a setter or constructor injection. Whatever suits your specific situation best.
If there's a lot (more than three ;-) ) of such values to be injected, you may consider introducing a configuration class to inject all those values as a single parameter.

EasyMock: call order on mocks created with #Mock

Is there any way to verify methods call order between mocks if they are created with #Mock annotation?
As described in documentation it can be done with a mock control. But EasyMockRule does not expose control object.
I have looked at EasyMockSupport implementation, but have not found way to force it to use one control for all injected mocks. :(
public class Test extends EasyMockSupport {
#Rule
public EasyMockRule mocks = new EasyMockRule(this);
#Mock
private SomeClass first;
#Mock
private OtherClass second;
#TestSubject
private UnderTest subject = new UnderTest ();
#Test
public void test() {
expect(first.call());
expect(second.call());
....
//Verify that calls were in order first.call(), second.call()
}
}
You are right, it is not possible. An enhancement could be to allow to set a control in the #Mock annotation. Can you please file an issue?
In your case, you will have to create the mocks manually using the same IMocksControl like explained in the documentation.

Injecting #Autowired private field during testing

I have a component setup that is essentially a launcher for an application. It is configured like so:
#Component
public class MyLauncher {
#Autowired
MyService myService;
//other methods
}
MyService is annotated with the #Service Spring annotation and is autowired into my launcher class without any issues.
I would like to write some jUnit test cases for MyLauncher, to do so I started a class like this:
public class MyLauncherTest
private MyLauncher myLauncher = new MyLauncher();
#Test
public void someTest() {
}
}
Can I create a Mock object for MyService and inject it into myLauncher in my test class? I currently don't have a getter or setter in myLauncher as Spring is handling the autowiring. If possible, I'd like to not have to add getters and setters. Can I tell the test case to inject a mock object into the autowired variable using an #Before init method?
If I'm going about this completely wrong, feel free to say that. I'm still new to this. My main goal is to just have some Java code or annotation that puts a mock object in that #Autowired variable without me having to write a setter method or having to use an applicationContext-test.xml file. I would much rather maintain everything for the test cases in the .java file instead of having to maintain a separate application content just for my tests.
I am hoping to use Mockito for the mock objects. In the past I have done this by using org.mockito.Mockito and creating my objects with Mockito.mock(MyClass.class).
You can absolutely inject mocks on MyLauncher in your test. I am sure if you show what mocking framework you are using someone would be quick to provide an answer. With mockito I would look into using #RunWith(MockitoJUnitRunner.class) and using annotations for myLauncher. It would look something like what is below.
#RunWith(MockitoJUnitRunner.class)
public class MyLauncherTest
#InjectMocks
private MyLauncher myLauncher = new MyLauncher();
#Mock
private MyService myService;
#Test
public void someTest() {
}
}
The accepted answer (use MockitoJUnitRunner and #InjectMocks) is great. But if you want something a little more lightweight (no special JUnit runner), and less "magical" (more transparent) especially for occasional use, you could just set the private fields directly using introspection.
If you use Spring, you already have a utility class for this : org.springframework.test.util.ReflectionTestUtils
The use is quite straightforward :
ReflectionTestUtils.setField(myLauncher, "myService", myService);
The first argument is your target bean, the second is the name of the (usually private) field, and the last is the value to inject.
If you don't use Spring, it is quite trivial to implement such a utility method. Here is the code I used before I found this Spring class :
public static void setPrivateField(Object target, String fieldName, Object value){
try{
Field privateField = target.getClass().getDeclaredField(fieldName);
privateField.setAccessible(true);
privateField.set(target, value);
}catch(Exception e){
throw new RuntimeException(e);
}
}
Sometimes you can refactor your #Component to use constructor or setter based injection to setup your testcase (you can and still rely on #Autowired). Now, you can create your test entirely without a mocking framework by implementing test stubs instead (e.g. Martin Fowler's MailServiceStub):
#Component
public class MyLauncher {
private MyService myService;
#Autowired
MyLauncher(MyService myService) {
this.myService = myService;
}
// other methods
}
public class MyServiceStub implements MyService {
// ...
}
public class MyLauncherTest
private MyLauncher myLauncher;
private MyServiceStub myServiceStub;
#Before
public void setUp() {
myServiceStub = new MyServiceStub();
myLauncher = new MyLauncher(myServiceStub);
}
#Test
public void someTest() {
}
}
This technique especially useful if the test and the class under test is located in the same package because then you can use the default, package-private access modifier to prevent other classes from accessing it. Note that you can still have your production code in src/main/java but your tests in src/main/test directories.
If you like Mockito then you will appreciate the MockitoJUnitRunner. It allows you to do "magic" things like #Manuel showed you:
#RunWith(MockitoJUnitRunner.class)
public class MyLauncherTest
#InjectMocks
private MyLauncher myLauncher; // no need to call the constructor
#Mock
private MyService myService;
#Test
public void someTest() {
}
}
Alternatively, you can use the default JUnit runner and call the MockitoAnnotations.initMocks() in a setUp() method to let Mockito initialize the annotated values. You can find more information in the javadoc of #InjectMocks and in a blog post that I have written.
I believe in order to have auto-wiring work on your MyLauncher class (for myService), you will need to let Spring initialize it instead of calling the constructor, by auto-wiring myLauncher. Once that is being auto-wired (and myService is also getting auto-wired), Spring (1.4.0 and up) provides a #MockBean annotation you can put in your test. This will replace a matching single beans in context with a mock of that type. You can then further define what mocking you want, in a #Before method.
public class MyLauncherTest
#MockBean
private MyService myService;
#Autowired
private MyLauncher myLauncher;
#Before
private void setupMockBean() {
doNothing().when(myService).someVoidMethod();
doReturn("Some Value").when(myService).someStringMethod();
}
#Test
public void someTest() {
myLauncher.doSomething();
}
}
Your MyLauncher class can then remain unmodified, and your MyService bean will be a mock whose methods return values as you defined:
#Component
public class MyLauncher {
#Autowired
MyService myService;
public void doSomething() {
myService.someVoidMethod();
myService.someMethodThatCallsSomeStringMethod();
}
//other methods
}
A couple advantages of this over other methods mentioned is that:
You don't need to manually inject myService.
You don't need use the Mockito runner or rules.
I'm a new user for Spring. I found a different solution for this. Using reflection and making public necessary fields and assign mock objects.
This is my auth controller and it has some Autowired private properties.
#RestController
public class AuthController {
#Autowired
private UsersDAOInterface usersDao;
#Autowired
private TokensDAOInterface tokensDao;
#RequestMapping(path = "/auth/getToken", method = RequestMethod.POST)
public #ResponseBody Object getToken(#RequestParam String username,
#RequestParam String password) {
User user = usersDao.getLoginUser(username, password);
if (user == null)
return new ErrorResult("Kullanıcıadı veya şifre hatalı");
Token token = new Token();
token.setTokenId("aergaerg");
token.setUserId(1);
token.setInsertDatetime(new Date());
return token;
}
}
And this is my Junit test for AuthController. I'm making public needed private properties and assign mock objects to them and rock :)
public class AuthControllerTest {
#Test
public void getToken() {
try {
UsersDAO mockUsersDao = mock(UsersDAO.class);
TokensDAO mockTokensDao = mock(TokensDAO.class);
User dummyUser = new User();
dummyUser.setId(10);
dummyUser.setUsername("nixarsoft");
dummyUser.setTopId(0);
when(mockUsersDao.getLoginUser(Matchers.anyString(), Matchers.anyString())) //
.thenReturn(dummyUser);
AuthController ctrl = new AuthController();
Field usersDaoField = ctrl.getClass().getDeclaredField("usersDao");
usersDaoField.setAccessible(true);
usersDaoField.set(ctrl, mockUsersDao);
Field tokensDaoField = ctrl.getClass().getDeclaredField("tokensDao");
tokensDaoField.setAccessible(true);
tokensDaoField.set(ctrl, mockTokensDao);
Token t = (Token) ctrl.getToken("test", "aergaeg");
Assert.assertNotNull(t);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
I don't know advantages and disadvantages for this way but this is working. This technic has a little bit more code but these codes can be seperated by different methods etc. There are more good answers for this question but I want to point to different solution. Sorry for my bad english. Have a good java to everybody :)
Look at this link
Then write your test case as
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"/applicationContext.xml"})
public class MyLauncherTest{
#Resource
private MyLauncher myLauncher ;
#Test
public void someTest() {
//test code
}
}

Junit - run set up method once

I set up a class with a couple of tests and rather than using #Before I would like to have a setup method that executes only once before all tests. Is that possible with Junit 4.8?
Although I agree with #assylias that using #BeforeClass is a classic solution it is not always convenient. The method annotated with #BeforeClass must be static. It is very inconvenient for some tests that need instance of test case. For example Spring based tests that use #Autowired to work with services defined in spring context.
In this case I personally use regular setUp() method annotated with #Before annotation and manage my custom static(!) boolean flag:
private static boolean setUpIsDone = false;
.....
#Before
public void setUp() {
if (setUpIsDone) {
return;
}
// do the setup
setUpIsDone = true;
}
You can use the BeforeClass annotation:
#BeforeClass
public static void setUpClass() {
//executed only once, before the first test
}
JUnit 5 now has a #BeforeAll annotation:
Denotes that the annotated method should be executed before all #Test
methods in the current class or class hierarchy; analogous to JUnit
4’s #BeforeClass. Such methods must be static.
The lifecycle annotations of JUnit 5 seem to have finally gotten it right! You can guess which annotations available without even looking (e.g. #BeforeEach #AfterAll)
When setUp() is in a superclass of the test class (e.g. AbstractTestBase below), the accepted answer can be modified as follows:
public abstract class AbstractTestBase {
private static Class<? extends AbstractTestBase> testClass;
.....
public void setUp() {
if (this.getClass().equals(testClass)) {
return;
}
// do the setup - once per concrete test class
.....
testClass = this.getClass();
}
}
This should work for a single non-static setUp() method but I'm unable to produce an equivalent for tearDown() without straying into a world of complex reflection... Bounty points to anyone who can!
JUnit 5 #BeforeAll can be non static provided the lifecycle of the test class is per class, i.e., annotate the test class with a #TestInstance(Lifecycle.PER_CLASS) and you are good to go
Edit:
I just found out while debugging that the class is instantiated before every test too.
I guess the #BeforeClass annotation is the best here.
You can set up on the constructor too, the test class is a class after all.
I'm not sure if it's a bad practice because almost all other methods are annotated, but it works. You could create a constructor like that:
public UT () {
// initialize once here
}
#Test
// Some test here...
The ctor will be called before the tests because they are not static.
Use Spring's #PostConstruct method to do all initialization work and this method runs before any of the #Test is executed
Try this solution:
https://stackoverflow.com/a/46274919/907576 :
with #BeforeAllMethods/#AfterAllMethods annotation you could execute any method in Test class in an instance context, where all injected values are available.
My dirty solution is:
public class TestCaseExtended extends TestCase {
private boolean isInitialized = false;
private int serId;
#Override
public void setUp() throws Exception {
super.setUp();
if(!isInitialized) {
loadSaveNewSerId();
emptyTestResultsDirectory();
isInitialized = true;
}
}
...
}
I use it as a base base to all my testCases.
If you don't want to force a declaration of a variable that is set and checked on each subtest, then adding this to a SuperTest could do:
public abstract class SuperTest {
private static final ConcurrentHashMap<Class, Boolean> INITIALIZED = new ConcurrentHashMap<>();
protected final boolean initialized() {
final boolean[] absent = {false};
INITIALIZED.computeIfAbsent(this.getClass(), (klass)-> {
return absent[0] = true;
});
return !absent[0];
}
}
public class SubTest extends SuperTest {
#Before
public void before() {
if ( super.initialized() ) return;
... magic ...
}
}
I solved this problem like this:
Add to your Base abstract class (I mean abstract class where you initialize your driver in setUpDriver() method) this part of code:
private static boolean started = false;
static{
if (!started) {
started = true;
try {
setUpDriver(); //method where you initialize your driver
} catch (MalformedURLException e) {
}
}
}
And now, if your test classes will extends from Base abstract class -> setUpDriver() method will be executed before first #Test only ONE time per run.
Here is one alternative suggestion:
What I do to get this working is
Create a method named _warmup or just _
Annotate the test class with #FixMethodOrder(MethodSorters.NAME_ASCENDING)
This is applicable only if you run all tests in the class
It has a downside of having additional test included, which will also run one additional #Before and #After
It is usually advised for your test methods to be order independent, this breaks that rule, but why someone would like tests ordered randomly in the reports I have no clue so NAME_ASCENDING is what I always use
But the upsides to this is simple setup with minimal code and without the need to extend classes/runners etc...
Test run lengths are more accurate since all setup time is reported on method _warmup
After experimenting for some time this is my solution. I needed this for spring boot test. I tried using #PostConstruct, unfortunately it is executed for every test.
public class TestClass {
private static TestClass testClass = null;
#Before
public void setUp() {
if (testClass == null) {
// set up once
...
testClass = this;
}
}
#AfterClass
public static void cleanUpAfterAll() {
testClass.cleanUpAfterAllTests();
}
private void cleanUpAfterAllTests() {
// final cleanup after all tests
...
}
#Test
public void test1() {
// test 1
...
}
#Test
public void test2() {
// test 2
...
}
}
The problem with #BeforeClass is that it fires before the constructor.
So if you rely on an #Autowired constructor to provide data, it simply will not work: wrong execution order.
Similarly #PostConstruct fires after the constructor has been called. And the constructor fires with every #Test, therefore your setup function will fire with every test, if you use this.
This has the exact same effect as calling a function from the constructor.
The only solution, I found that works, is to use a flag to indicate if the setUp() method has already been executed. While its not ideal, it will drastically reduce the amount of processing before each test.
private static boolean initialized = false;
#Autowired
public CacheTest( MyBean myBean ){
this.myBean = myBean;
}
#PostConstruct
public static void setUp(){
if( initialized ) { return };
initialized = true;
//do suff with myBean
}

Categories