method is not called inside another method in JUnit - spring-boot

I have a method that calls another mehide inside.
Here is my method:
public void unblocUser(BloclistDTO bloclistDTO) {
blocListRepository.delete(mapper.toModel(bloclistDTO));
if (blocListRepository.getBlocList(bloclistDTO.getCandidate().getId(), bloclistDTO.getColumnName()).isEmpty()) {
this.setVisibility(bloclistDTO.getCandidate().getId(), bloclistDTO.getColumnName(), true);
}
}
I've tested the method setVisibility itself, it works. But, when clling unblocUser it doesn't work ;
Here is how am testing it:
#Test
public void unblocUserLastOne() {
Company blockedCompany = new Company ();
Candidate candidate = new Candidate ();
candidate.setId(1L);
candidate.setPersonalDetailsVisible(false);;
blockedCompany.setId(2L);
candidate.setPersonalDetailsVisible(false);
BloclistDTO bloclist= new BloclistDTO();
bloclist.setBlockedCandidate(null);
bloclist.setCandidate(candidate);
bloclist.setBlockedCompany(blockedCompany);
bloclist.setColumnName("personal_details_visible");
bloclist.setId(3L);
blocListService.unblocUser(bloclist);
assertEquals(true, candidate.isPersonalDetailsVisible());
}
I get an error : expected true but was false.
Any help please ?

first you need to create a mock object for BlocListRepository class
#InjectMocks
BlocListRepository blocListRepository;
Then mock the delete method in BlocListRepository class.
#Test
public void unblocUserLastOne() {
Mockito.doNothing().when(blocListRepository).delete(Mockito.any());
Company blockedCompany = new Company ();
Candidate candidate = new Candidate ();
candidate.setId(1L);
candidate.setPersonalDetailsVisible(false);;
blockedCompany.setId(2L);
candidate.setPersonalDetailsVisible(false);
BloclistDTO bloclist= new BloclistDTO();
bloclist.setBlockedCandidate(null);
bloclist.setCandidate(candidate);
bloclist.setBlockedCompany(blockedCompany);
bloclist.setColumnName("personal_details_visible");
bloclist.setId(3L);
blocListService.unblocUser(bloclist);
assertEquals(true, candidate.isPersonalDetailsVisible());
}

Related

How can I get a VaadinView-#QuarkusTest up and running?

Assume you have the provided Vaadin view (1) and you want to test it with the #QuarkusTest (2) similar as depicted here (3) but not for Vaadin-on-SpringBoot but for Vaadin-on-Quarkus.
I get a NPE:
Caused by: java.lang.NullPointerException:
Cannot invoke "io.quarkus.arc.InjectableContext.isActive()" because
the return value of "com.vaadin.quarkus.context.UIContextWrapper.getContext()" is null
Questions:
Does anyone know how to fix this?
Are Quarkus-Tests of this kind already supported by the vaadin quarkus extension?
Do I have to add a missing test-only-dependency I do not yet know of?
Sidenotes:
The View and Test had been added to the Quarkus-Vaadin-Sample-CRM provided here: https://github.com/mstahv/quarkus-crm.git
The NPE occurs with the original version setting (Vaadin=23.0.1|Quarkus=2.7.4.Final) as well as with an update (Vaadin=23.3.4|Quarkus=2.15.3.Final)
The Vaadin-Quarkus-Template does not (yet) come along with a sample #QuarkusTest.
(1)
#UIScoped
#Route(value = "testshowcase", layout = MainLayout.class)
#PageTitle("Testing showcase")
#PermitAll
public class TestingShowcaseView extends HorizontalLayout {
TextField textFieldInput = new TextField("Eingabe");
TextField textFieldOutput = new TextField("Ausgabe");
Button btnProcess = new Button("To Upper");
#Inject
TestingShowcaseService testingShowcaseService;
#PostConstruct
public void init() {
btnProcess.addClickListener(e -> {
textFieldOutput.setValue(testingShowcaseService.toUpper(textFieldInput.getValue()));
});
VerticalLayout barInput = new VerticalLayout(textFieldInput, btnProcess);
VerticalLayout barOutput = new VerticalLayout(textFieldOutput);
add(barInput, barOutput);
}
}
#RequestScoped
public class TestingShowcaseService {
public String toUpper(String whatever) {
if (whatever == null) {
return null;
} else {
return whatever.toUpperCase();
}
}
}
(2)
#QuarkusTest
public class TestingShowcaseViewQuarkusTest {
#Inject
TestingShowcaseView testingShowcaseView;
#Test
public void testServiceInteraction() {
String actualOutput;
actualOutput = testingShowcaseView.textFieldOutput.getValue();
Assertions.assertNull(actualOutput, "... was '%s'.".formatted(actualOutput));
testingShowcaseView.btnProcess.click();
actualOutput = testingShowcaseView.textFieldOutput.getValue();
Assertions.assertEquals("RubbeldieKatz", actualOutput);
}
}
(3) [https://vaadin.com/docs/latest/tutorial/unit-and-integration-testing/#creating-and-running-integration-tests-for-more-advanced-ui-logic]

Mockito, how to mock call by reference method on same class

Why I can not mock callRefMethod method (call method by reference) on below code? The problem is real method of callRefMethod always being called.
public class ManageUserService {
public void callRefMethod(List<String> lsStr, boolean flag){
if (flag){
lsStr.add("one");
lsStr.add("two");
}
}
public void methodA(){
List<String> lsStr = new ArrayList<>();
lsStr.add("zero");
this.callRefMethod(lsStr, true);
for(String str : lsStr){
System.out.println(str);
}
}
}
Unit tests:
public class ManageUserServiceTest {
#InjectMocks
private ManageUserService manageUserService;
private AutoCloseable closeable;
#BeforeEach
public void init() {
closeable = MockitoAnnotations.openMocks(this);
}
#AfterEach
void closeService() throws Exception {
closeable.close();
}
#Test
void methodATest(){
List<String> lsData = new ArrayList<>();
lsData.add("start");
ManageUserService manageUserServiceA = new ManageUserService();
ManageUserService userSpy = spy(manageUserServiceA);
doNothing().when(userSpy).callRefMethod(lsData, true);
userSpy.methodA();
verify(userSpy).callRefMethod(ArgumentMatchers.any(ArrayList.class), ArgumentMatchers.any(Boolean.class));
}
}
The result :
zero
one
two
The problem is the difference between the list you're creating in the test method, which is used to match the expected parameters when "doing nothing":
List<String> lsData = new ArrayList<>();
lsData.add("start");
...
doNothing().when(userSpy).callRefMethod(lsData, true);
and the list created in the tested method, passed to the spy object:
List<String> lsStr = new ArrayList<>();
lsStr.add("zero");
this.callRefMethod(lsStr, true);
You're telling Mockito to doNothing if the list is: ["start"], but such list is never passed to the callRefMethod. ["zero"] is passed there, which does not match the expected params, so actual method is called.
Mockito uses equals to compare the actual argument with an expected parameter value - see: the documentation. To work around that ArgumentMatchers can be used.
You can either fix the value added to the list in the test or match the expected parameter in a less strict way (e.g. using anyList() matcher).
ok i did it by using : where manageUserServiceOne is spy of ManageUserService class
void methodATest(){
List<String> lsData = new ArrayList<>();
lsData.add("start");
doAnswer((invocation) -> {
System.out.println(invocation.getArgument(0).toString());
List<String> lsModify = invocation.getArgument(0);
lsModify.add("mockA");
lsModify.add("mockB");
return null;
}).when(manageUserServiceOne).callRefMethod(anyList(), anyBoolean());
manageUserServiceOne.methodA();
verify(manageUserServiceOne).callRefMethod(ArgumentMatchers.any(ArrayList.class), ArgumentMatchers.any(Boolean.class));
}

thenThrow() not throwing an exception

I have a method in OneServiceImpl class as follows. In that class I am calling an interface method from another class.
public class OneServiceImpl {
//created dependency
final private SecondService secondService;
public void sendMessage(){
secondService.validateAndSend(5)
}
}
public interface SecondService() {
public Status validateAndSend(int length);
}
public class SecondServiceImpl {
#Override
public Status ValidateAndSend(int length) {
if(length < 5) {
  throw new BadRequestException("error", "error");
}
}
}
Now when I am try to perform unit test on OneServiceImpl I am not able to throw a BadRequestException.
when(secondService.validateAndSend(6)).thenThrow(BadRequestException.class);
Not quite sure what your use case is, but I think you should write an own test to accept and test an exception.
#Test(expected = BadRequestException.class)
public void testValidateAndSend(){
SecondService secondService = new SecondService();
secondservice.ValidateAndSend(6); //method should be lowercase
}
Not sure this is the case considering you didn't post a full example of code + unit tests, but your mock will throw only when you are passing 6 as parameter. When configuring the behaviour of your mock with when you are telling it to throw only when the validateAndSend method is called with parameter 6.
when(secondService.validateAndSend(6)).thenThrow(...)
In your code you have 5 hardcoded. So that mock will never throw for the code you have, because it's configured to react to an invocation with parameter 6 but the actual code is always invoking it passing 5.
public void sendMessage(){
secondService.validateAndSend(5)
}
If the value passed to the mock is not important you could do something like the following, that will throw no matter what's passed to it:
when(secondService.validateAndSend(any())).thenThrow(BadRequestException.class);
On the other hand, if the value is important and it has to be 5 you could change the configuration of your mock with:
when(secondService.validateAndSend(5)).thenThrow(BadRequestException.class)

Test Observable.FlatMap Mockito

I've been looking on internet but haven't found the solution if any (new on UnitTest and Mockito)
It's possible to test a method that return a call of a service and manipulate it's result before to return it? Example;
public Observable<Reports> getUserReports(Integer userId) {
return serviceClient
.getReports(userId)
.flatMap(serviceReports -> {
System.out.println("Testing inside flatMap"); <- never reach this line therefore duno if methods down here are invoked and work perfectly
final Observable<List<Report>> reports = getPendingReports(userId, serviceReports);
//More methods that modify/update information
return zip(observable1, observable2, observable3
(report1, report2, report3) -> {
updateReports(otherArguments, report1, report2, report3);
return serviceReports;
});
});
}
So far I've tried;
#Test
public void myTest(){
when(serviceClient
.getReports(anyInt()))
.thenReturn(Observable.just(reports));
Observable<Reports> result = mocketClass.getUserReports(userId)
}
Tryed with Spy and Mock but no luck so far. Any hint or help would be great.
To mock getReports() behavior you need to mock the serviceClient firstly and pass it into your service class.
Just as example:
#Test
public void myTest(){
// Given
final ServiceClient mockedServiceClient = Mockito.mock(ServiceClient.class);
when(mockedServiceClient
.getReports(anyInt()))
.thenReturn(Observable.just(reports));
// and create an instance of your class under testing with injected mocked service client.
final MyUserService userService = new MyUserService();
userService.setServiceClient(mockedServiceClient);
// When run a method under test
Observable<Reports> actualResult = userService.getUserReports(userId)
// Then
// actualResult to be verified.
}

Beginners Moq question on Verifying

I'm just playing around with Moq and I cannot work out how to get a call to Verify to work as expected. My problem seems to be that the method I'm calling on the SUT is not being called. Here's my code to test:
public class ImageHandler : BaseHttpHandler
{
public override void ProcessRequest(HttpContextBase context)
{
var person = new Person();
this.DoPerson(person);
context.Response.ContentType = "image/jpeg";
if (context.Request.RawUrl.ToLower().Contains("jellyfish.jpg"))
{
context.Response.TransmitFile(#"C:\Temp\jf.jpg");
}
else if (context.Request.RawUrl.ToLower().Contains("koala.jpg"))
{
context.Response.TransmitFile(#"C:\Temp\k.jpg");
}
else
{
context.Response.Write("File not found.");
}
}
public virtual void DoPerson(Person person)
{
}
}
Here is my MSpec test:
[Subject("Process")]
public class When_Given_Person
{
private static Mock<HttpContextBase> httpContext;
private static Mock<HttpRequestBase> httpRequest;
private static Mock<HttpResponseBase> httpResponse;
private static Mock<ImageHandler> mockSut;
private static BaseHttpHandler sut;
private Establish context = () =>
{
httpContext = new Mock<HttpContextBase>();
httpResponse = new Mock<HttpResponseBase>();
httpRequest = new Mock<HttpRequestBase>();
mockSut = new Mock<ImageHandler>();
httpContext.SetupGet(context => context.Response).Returns(httpResponse.Object);
httpContext.SetupGet(context => context.Request).Returns(httpRequest.Object);
httpRequest.SetupGet(r => r.RawUrl).Returns("http://logicsoftware/unkown.jpg");
sut = mockSut.Object;
};
private Because of = () => sut.ProcessRequest(httpContext.Object);
private It should_call_person_with_expected_age = () =>
{
mockSut.Verify(s => s.DoPerson(Moq.It.IsAny<Person>()),Times.AtLeastOnce());
};
}
This is really basic stuff, nothing too fancy. Now, when I run the test I get:
Expected invocation on the mock at least once, but was never
performed: s => s.DoPerson(It.IsAny()) No setups configured.
I believe this is due to the fact that sut.ProcessRequest() is not actually called - I have a breakpoint at the start of ProcessRequest(), but it's never hit. Can someone show me how to setup my mockSut so that ProcessRequest() is called.
Cheers.
Jas.
When you make a Mock of an object with Moq, it will mock the whole object and set it up to return defaults or do nothing on every method and property. So sut.ProcessRequest, won't actually do anything: DoPerson will never be called.
You'll only want to mock out dependencies to the classes you want to test, never the class itself.

Resources