Mock the Model Mapper Strict Strategy in java - junit

I need to mock the following Model Mapper Strict strategy configuration with the mockito.
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
I tried the following in my test method but i am getting Null Pointer Exception.
#Test
public void mockModelMapper(){
when(modelmapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT))
.thenReturn(modelmapper.getConfiguration());
}
Thanks in advance.

As mentioned by #DCTID, you can't chain the mocks. You need to split each method call and inject a mock for the object returned by getConfiguration().
#Test
public void mockModelMapper(){
// Inject the configuration mock
Configuration configurationMock = mock(Configuration.class);
when(configurationMock.setMatchingStrategy(MatchingStragegies.STRICT)
.thenReturn(configuraitonMock);
when(modelmapper.getConfiguration()).thenReturn(configurationMock);
}

Related

Annotation for method, which must work before a group of features (Cucumber + Junit)

Cucumber supports hooks -- methods that run before or after a scenario.
The #Before and #After annotations are used to mark them.
A method with #Before annotation will run before each scenario, #After -- after each scenario.
An example of a class with hooks:
public class Hooks {
#Before
public void init() {
System.out.println("before each Cucumber scenario");
}
#After
public void stop() {
System.out.println("after each Cucumber scenario");
}
}
Can you tell me, please, what annotations I must use in order to run method 1 time before the entire group of Cucumber-scenarios (feature-files)?
If there is no such annotation, then how can we do it in another way?
You can use the standard Junit annotation #BeforeAll and #AfterAll
#BeforeAll methods are only executed once for a given test class.
#BeforeAll is used to signal that the annotated method should be executed before all tests in the current test class.
Please refer this documentation #BeforeAll

Unable to Mock functions inside static method Powermock

I am writing unit test for the below code using junit and mockito
public class Abc implements Runnable
{
private static ServerSocket server;
private static int port;
public Abc(int cPort)
{
port = cPort;
}
public void run()
{
init();
}
public static void init()
{
try {
server = new ServerSocket(port);
...something...
client.close();
}
}
catch(IOException e)
{
System.out.println("Exception inside init()...");
e.printStackTrace();
}
}
};
Unit test I have written
#RunWith(PowerMockRunner.class)
#PrepareForTest({ServerSocket.class})
public class abcTest {
#Mock (name = "server") //same name as private var.
ServerSocket mockServer;
#InjectMocks
Abc abc;
#Test
public void testInit() throws Exception {
int port = 1880;
Socket mockClient = Mockito.mock(Socket.class);
PowerMockito.whenNew(ServerSocket.class).
withArguments(anyInt()).thenReturn(mockServer);
abc = new Abc(port);
Abc.init();
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
};
But the call always go to original function definition. I am using junit 4.11 with mockito 2.28.2 and powermockito 2.0.2. I'm using java after a long time. Now its feel like kind of new. Please correct me if anything wrong in the code also.
You will need to change your PrepareForTest annotation
to #PrepareForTest({Abc.class}).
From the PowerMockito docu:
This annotation tells PowerMock to prepare certain classes for testing. Classes needed to be defined using this annotation are typically those that needs to be byte-code manipulated
In this case that refers to the class which creates the new instance of ServerSocket. ServerSocket itself is a non-final public class that does not require special handling from PowerMockito (instead Mockito can deal with this class on its own).
You could also change your test to do the following:
#Test
public void testInit() throws Exception {
int port = 1880;
ServerSocket mockServer = Mockito.mock(ServerSocket.class);
PowerMockito.whenNew(ServerSocket.class)
.withArguments(Mockito.anyInt()).thenReturn(mockServer);
Abc.port = port;
Abc.init();
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
(This first point is unrelated to whether the test fails or succeeds)
I do not know why you mix object's and static method behaviour together, but I think you should change that.In the test instead of creatic an ABC object, just could just set the static port variable directly.
Or alternatively change the whole ABC class into an object.
#InjectMocks failed for me as there is no default constructor
(Actually I got an error message in the console when trying to execute your code)
Additonaly you create a new instance of ABC in your test, which would have overwritten the things done by the annotations. Also as server is created during the init call, there is no need to inject a mock for it.
powermockito 2.0.2 actually depends on junit 4.12, so I am not sure what effects downgrading to an older version might have.
Socket mockClient seemed somewhat unrelated to the code your posted, so I removed it from my example in the answer, however as you use a client (I assume that is your Socket) in your code your probably need to do some mocking for that as well and provide the mock to the method accordingly.

Mocking Spring Data Repository

I have a BeerRepository interface that extends JPARepository<Beer,UUID>. This interface contains this method.
Page<Beer> findAllByBeerName(String beerName, Pageable pageable);
In a controller handler method, I have this.
Page<Beer> pagedResult = beerRepository.findAllByBeerName(beer.getBeerName(),
createPageRequest(0,10,Sort.Direction.DESC,"beerName"));
I am trying to unit test the controller handler method.
The #BeforeEach method is this.
. . .
Page<Beer> pagedResponse;
#BeforeEach
void setUp() {
beerList = new ArrayList<Beer>();
beerList.add(Beer.builder().build());
beerList.add(Beer.builder().build());
pagedResponse = new PageImpl(beerList);
mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.build();
}
My #Test method is this.
#Test
void processFindFormReturnMany() throws Exception{
when(beerRepository.findAllByBeerName(anyString(), PageRequest.of(0,
10,Sort.Direction.DESC,"beerName"))).thenReturn(pagedResponse);
mockMvc.perform(get("/beers"))
.andExpect(status().isOk())
.andExpect(view().name("beers/beerList"))
.andExpect(model().attribute("selections", hasSize(2)));
}
On running the test, I'm getting
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
-> at
guru.sfg.brewery.web.controllers.BeerControllerTest.
processFindFormReturnMany
(BeerControllerTest.java:67)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
Any help on this will be highly appreciated.
The problem is: you cannot mix Mockito matchers with real values while mocking with when(...). See docs.
In your case the following should work correctly:
when(beerRepository.findAllByBeerName(anyString(), eq(PageRequest.of(0,
10,Sort.Direction.DESC,"beerName")))).thenReturn(pagedResponse);
or
when(beerRepository.findAllByBeerName(anyString(), any(PageRequest.class)).thenReturn(pagedResponse);
Finally, you can use the real expected string instead of anyString() and leave PageRequest.of(...) as is. It should work too (assuming that they were configured correctly).
You need to set mock class for param when you mock any method
when(beerRepository.findAllByBeerName(anyString(), any(Pageable.class)).thenReturn(pagedResponse);

Testing constructor when using #Before annotation

I want to test SomeClass methods.
For that, I need SomeClass instance in every test so I'm using #Before annotation and initiate an instance of SomeClass named SC.
The problem is:- How can I test the constructor function after I already use it? It doesn't make sense.
Additional question:- The constructor can get number of arguments and they can influnce the methods outputs, should I mock this class instead of creating an instance of it?
public class SomeClassTest {
SomeClass SC;
#Before
public void initlize() throws IOException{
SC= new SomeClass (argument1,argument2,..);
}
#Test
public void ConstructorTest() {
}
Just don't use the object SC in your ConstructorTest. If you wan't to test a certain outcome from the construction of a SomeClass object with certain parameters then just construct it as such within your ConstructorTest and then assert the relevant outcomes you expect on the newly constructed object.
And no you shouldn't be mocking this class. The test is for testing this class so if you mock it's behaviour then you aren't really testing anything.

Call a Rest method with mockito

I use Jersey and I have the following Rest function which returns a JSON string when my server is deployed:
#GET
#Path("getallemployees")
#Produces("application/json")
public Response getAllEmployees() {
//building the entity object which is List<Employee>
return Response.ok(entity).build();
}
I need to develop some unit tests (not integration testing) and I want to somehow mock the HTTPRequest that invokes this method and then get the json String. The best option would be to use mockito for this.
Is there any suggestion on how to do it ?
Thanks !!
The problem is that the method returns a Response object to the caller which is deep within the framework code. It doesn't return JSON strings.
You can use Mockito, if you need to mock something inside the method itself. That should work.
But you may need to take the value returned by the method and convert it to JSON like this if you are using Jackson with Jersey.
Response response = getAllEmployees();
Object retval = response.getEntity();
try {
ObjectMapper mapper = new ObjectMapper();
// I like this formatting. You can change it.
mapper.configure(Feature.INDENT_OUTPUT, true);
mapper.configure(Feature.WRITE_ENUMS_USING_TO_STRING, true);
mapper.configure(Feature.USE_ANNOTATIONS, false);
mapper.configure(Feature.FAIL_ON_EMPTY_BEANS, false);
mapper.setSerializationInclusion(Inclusion.NON_NULL);
mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
mapper.getSerializationConfig().withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
String json = mapper.writeValueAsString(retval);
... assert something about the string
} catch (JsonProcessingException e) {
// do something
} catch (IOException e) {
// do something
}
Some of this is guess work and speculation on my part but it may help. You could try using the Jersey Test Framework with the InMemoryTestContainerFactory:
It starts Jersey application and directly calls internal APIs to handle request created by client provided by test framework. There is no network communication involved. This containers does not support servlet and other container dependent features, but it is a perfect choice for simple unit tests.
It looks like to use it, all you need to do is extend JerseyTest and then override getTestContainerFactory() and follow the rest of the instructions, e.g.:
public class EmployeeResourceTest extends JerseyTest {
#Override
protected Application configure() {
// set up employee resource with mock dependencies etc...
return new ResourceConfig().registerInstances(employeeResource);
}
#Test
public void getAllEmployees() {
final String response = target("getallemployees").request().get(String.class);
// assert etc...
}
}
I used registerInstances instead of registerClasses in configure() as it looks like you can present a ready made Resource but set up with any mock dependencies you may want - although I haven't tried this myself.
The test class is a bit inflexible as you can only do one-time set up of dependencies in the configure() method, so it might be worth investigating using the MockitoJUnitRunner - although I'm not sure if it will work with the JerseyTest inheritance. It could allow you to do add behaviour to mocks in each #Test method, e.g.:
#Mock
private EmployeeResourceDependency dependency;
#InjectMocks
private EmployeeResource employeeResource;
// configure() as above but without mock setup up etc...
#Test
public void getAllEmployees() {
given(dependency.getEmployees()).willReturn(...);
// etc...
But like I said it might not be possible to mix them at all.