Assuming that I have this repository
#Repository public class GenericHistoryRepositoryImpl implements GenericHistoryRepository {
#Autowired private MongoTemplate mongoTemplate;
#Override public Historiable create(Historiable historiableObject, String collectionName) {
mongoTemplate.save(historiableObject, collectionName);
return historiableObject; }
#Override public <T extends Historiable> T get(String id, Class<T> collectionClass, String collectionName) {
Query query = new Query();
query.addCriteria(Criteria.where("id").is(id));
return mongoTemplate.findOne(query, collectionClass, collectionName);
} }
And I have this test in which I have to mock the repository, but I can't figure out how
#RunWith(MockitoJUnitRunner.class)
public class GenericHistoryServiceTest {
#Mock
private GenericHistoryRepository genericHistoryRepository;
#InjectMocks
private GenericHistoryService genericHistoryService = new GenericHistoryServiceImpl();
#Test
public <T extends Historiable> void getHistoryOk2() throws NotFoundException, ClassNotFoundException {
String id = "1"
;
String collectionName = HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST;
ShipmentRequest a = mock(ShipmentRequest.class);
Class<? extends Historiable> clazz = ShipmentRequest.class;
when(genericHistoryRepository.get(any(String.class), eq(clazz), collectionName)).thenReturn(createExample());
HistoriableDTO result = genericHistoryService.get(id, HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST);
// verify(genericHistoryRepository, times(1)).get(id, any(), HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST);
assertThat(result, is(notNullValue()));
assertThat(result.getId(), is(notNullValue()));
}
Keep in mind that Historiable is an abstract class
public abstract class Historiable {
public abstract String getParentId();
}
And this extends Historiable
#Document(collection = HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST)
public class ShipmentRequest extends Historiable {
private String id;
#Indexed
private String parentId;
...
}
My problem is with the "when" sentence defining the behaviour of the repository mock. It has generic methods that I don't know how to mock
Class<? extends Historiable> clazz = ShipmentRequest.class;
when(genericHistoryRepository.get(any(String.class), eq(clazz), collectionName)).thenReturn(createExample());
I'm getting
The method thenReturn(capture#1-of ? extends Historiable) in the type OngoingStubbing<capture#1-of ? extends Historiable> is not applicable for the arguments (ShipmentRequest)
private ShipmentRequest createExample() {
ShipmentRequest history = new ShipmentRequest();
history.setId("1");
return history;
}
Your when clause is the problem.
Inside the when you should define when to match and after that you state what should be returned.
Your when statement starts good by stating you want to match any String passed as first argument, but as a second argument you are passing a mock so that means that it will only trigger if that specific mock is passed as second argument (which I don't think is happening).
You can change the second argument to: any(Class.class)
For the third argument you can state that you want it to be equal to collectionName by using: org.mockito.ArgumentMatchers#eq(T)
In your test class you can have something like this
public class TestClass {
#Mock
GenericHistoryRepository genericHistoryRepository;
#InjectMock
MongoTemplate mongoTemplate;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
}
#InjectMock will inject the depedency of your mock.
Related
I try to learn PowerMockitoand write a demo
This the parent class A
public abstract class A {
protected String getRoot(Long id) {
if (id == 0) {
return "root";
}
return "not root";
}
}
And this is the childA
public class ChildA extends A {
private String info;
public String getRootInfo(Long id) {
String rootInfo = getRoot(id);
return rootInfo;
}
private void initRootInfo(String info) {
this.info = info;
}
}
And now i want to mock the method A::initRootInfo,so i write a test case like this
#RunWith(PowerMockRunner.class)
#PrepareForTest({A.class, ChildA.class})
public class ChildATest {
#Spy
#InjectMocks
private ChildA childA = PowerMockito.spy(new ChildA());
#Test
public void getRootInfoUT() throws Exception {
PowerMockito.doNothing().when(childA, "initRootInfo", Mockito.anyString());
String rootInfo = childA.getRootInfo(0L);
Assertions.assertEquals("root", rootInfo);
}
}
When i run the test case, the PowerMockito call the real method initRootInfo, so that i get a little bit confused why the A::initRootInfo will be called really, shouldn't it be mock and replaced by PowerMockito? is there have something wrong i use PowerMockito?
How to mock private method by PowerMockito correctly
I have a class where I want to write a junit test for.
This method has no parameters, can this method accordingly?
public class classTobeTested {
#Self
SlingHttpServletRequest request;
static final String keyword = "hello";
public boolean isActive() {
boolean check;
String pathChecker;
pathChecker = (request.getRequestURL()).toString();
check= pathChecker.contains(keyword);
return check;
}
}
This would be the testing class i had in mind
#RunWith(MockitoJUnitRunner.class)
public class testclasstobetested {
#Test
public void TestclassTobeTested() throws Exception{
classTobeTested CTT = new classTobeTested();
assertFalse(CTT.isActive("hello how are you"));
}
}
I know my method does not take a parameter but has strings declared inside the method.
How can i use assertFalse correctly to test a non param method.
Using annotations and Junit4 you can do it like this:
#RunWith(MockitoJUnitRunner.class)
public class testclasstobetested {
#InjectMocks
private classTobeTested CTT;
#Mock
private SlingHttpServletRequest request;
#Test
public void TestclassTobeTested() throws Exception{
when(request.getRequestURL()).thenReturn(new StringBuffer("hello how are you"));
assertFalse(CTT.isActive());
}
}
I am using Mockito and have tried to mock the below test class.
Here the main class method createNewId() is getting the object by hitting dao class 'memberDao.findNext()'.
I am trying to mock 'memberDao.findNext()' and return the object as shown in below code but it is returning as NULL.
ALSO how to write Test for void method which is "memberDao.delete(newId.getId());"
Need to implement this after this line "when(memberDao.findNext()).thenReturn(id);"
Please let me know what am i doing wrong.
#RunWith(MockitoJUnitRunner.class)
public class MemberTest
{
#InjectMocks
private Member member;
#Mock
private MemberDao memberDao;
#Test
public void createId() throws Exception
{
MembersIdDto id = new MembersIdDto();
id.setId("967405286");
when(memberDao.findNext()).thenReturn(id);
verify(member).createNewId().contains("967405286");
}
public class Member {
#Resource
MemberDao memberDao;
public String createNewId()
{
MembersIdDto newId = memberDao.findNext();
Assert.notNull(newId, "newId is empty");
String id = newId.getId();
memberDao.delete(newId.getId());
return id;
}
}
memberDao.findNext() is the line i am trying to mock.
Error is :
java.lang.IllegalArgumentException: newId is empty
at org.springframework.util.Assert.notNull(Assert.java:134)
at Member.createNewId() (Member.java:20)
// Line 20 is "Assert.notNull(newId, "newId is empty");"
A working example of your requirement could be:
#RunWith(MockitoJUnitRunner.class)
public class MemberTest {
#InjectMocks
private Member member;
#Mock
private MemberDao memberDao;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void createId() throws Exception {
MembersIdDto dto = new MembersIdDto();
dto.setId("967405286");
when(memberDao.findNext()).thenReturn(dto);
assertThat(member.createNewId()).isEqualTo("967405286");
}
}
…with the classes-under-test…
public class Member {
#Resource
MemberDao memberDao;
public String createNewId() {
return memberDao.findNext().getId();
}
}
…and…
public class MemberDao {
public MembersIdDto findNext() {
return null; // or whatever
}
}
…and…
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#NoArgsConstructor
public class MembersIdDto {
private String id;
}
By the way, I use the AssertJ assertion framework and with member.createNewId() you have now a real call on production code.
You're creating two instances of MemberDao. First MockitoJUnitRunner creates an instance, assigns it to the field memberDao and injects that instance into the Member object. Afterwards in the method setUp you create a new instance of the DAO and assign it to the field memberDao. Therefore the field memberDao is no longer the same as the Member's DAO. While you define behaviour on the field, the Member object is still using the first DAO that has no behaviour defined. Therefore memberDao.findNext() in Member#createNewId returns null.
Fortunately the solution is very simple: Delete the setUp method in your test.
I am newbie in Java world, but it is very hard understand why not can I stub method of a mocked object...
#RunWith(MockitoJUnitRunner.class)
public class ChildBLLIT extends BaseInteractorIT {
#InjectMocks
private ChildBLL ChildBLL = Mockito.mock(ChildBLL.class);
#Before
public void setUp() {
ChildBLL.engine = engineMock;
}
/**
* Test of getZipStatistics method, of class ChildBLL.
*/
#Test
public void testGetZipStatistics() {
final String testZipStatisticsText = "DummyZipStatistics";
//This method will throw the null pointer exception
when(ChildBLL.engine.getZIPStatistics()).thenReturn(testZipStatisticsText);
ChildBLL.getZipStatistics();
verify(ChildBLL.engine).getZIPStatistics();
}
}
When I try to stub the getZIPStatistics() method I get always a null pointer exception, of course I get, because in the getZIPStatistics() method there is an private object, which is not mocked... it seems to me the Mockito does not mocking the private fields... and unfortunately this is from another project:
public class BaseIT {
#Mock
protected static FromOtherProject engineMock;
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
}
Here I mocked the engine variable, but then how can I mock/stub the getZIPStatistics() method? This is this method:
public class FromOtherProject {
//...
public final String getZIPStatistics() {
return ZIPStatistics.toString();
}
}
What can I do?
Let's assume a simple class...
public class Account {
public String getPassword() {
return "abc";
}
}
...and simple class that contains it...
public class AccountHolder {
private Account account;
public String getAccountPassword() {
return this.account.getPassword();
}
}
So now we have a simple base class for all Account based tests...
public class AccountBasedTest {
#Mock
protected Account account;
}
...and a class that actually tests the AccountHolder...
#RunWith(MockitoJUnitRunner.class)
public class AccountHolderTest extends AccountBasedTest {
#InjectMocks
private AccountHolder accountHolder;
#Test
public void getAccountPasswort_must_return_account_password() {
Mockito.when( this.account.getPassword() ).thenReturn ("xyz");
Assert.assertEquals("xyz", this.accountHolder.getAccountPassword());
}
}
And that's all. The #InjectMocks, etc. annotations will also look in the superclasses, so you get your mocked account and that account will be put into your AccountHolder. No need to call MockitoAnnotations.initMocks. It shouldn't hurt, but it's not needed because you are using the MockitoJUnitRunner already, which does exactly that.
#Component
public class SomeFactory implements ISomeFactory {
public someWatchFactory() {};
#Override
public boolean startWatch(MethodToWatch methodName, UUID uniqueID, Callable toRun) {
IPerformanceStopWatch mywatch = getStartWatch(methodName,uniqueID,toRun);
return mywatch.startWatchDeployTaskStatus();
}
#Lookup
private IPerformanceStopWatch getStartWatch(MethodToWatch methodName, String uniqueID, Callable toRun) {
IPerformanceStopWatch mywatch = getStartWatch(methodName,uniqueID,toRun);
return null; //stub implementation which will be replaced by the container
}
}
I would like to test the factory class, using something like:
#InjectMock
ISomeFactory someFactory;
#Mock
IPerformanceStopWatch performanceWatch
That whenever the lookup annotation inside the SomeFactory class will try to get the instance, it will use the mock.
How should i do it?