I am trying to make test cases junits for the function using selenium webelement as argument.
I am trying to mock the element but this test case is giving error. The method for which I am trying to make test case is this.
#Override
public boolean isDownloadStarted(WebDriver driver) {
boolean isDownloadStarted = false;
ArrayList<String> tabs = new ArrayList<>(driver.getWindowHandles());
if (tabs.size() == 1) {
isDownloadStarted = true;
}
return isDownloadStarted;
}
The test case is which is giving null pointer exception
DownloadStatusListenerImpl status;
#Before
public void before() {
MockitoAnnotations.initMocks(this);
status = new DownloadStatusListenerImpl();
}
#Test
public void testDownloadStatusListenerImpl() {
Mockito.when(status.isDownloadStarted(Mockito.any(WebDriver.class))).thenReturn(true);
assertEquals(true, status.isDownloadStarted(Mockito.any(WebDriver.class)));
}
You aren't stubbing the status. You could either add a #Spy annotation to it (and stop overwriting it):
#Spy // Annotation added here
DownloadStatusListenerImpl status;
#Before
public void before() {
MockitoAnnotations.initMocks(this);
// Stopped overwriting status here
}
Or you could explicitly call Mockito.spy:
#Before
public void before() {
status = Mockito.spy(new DownloadStatusListenerImpl());
}
EDIT:
Calling when on a method like this will still invoke it, and thus fail. You need to use the doReturn syntax instead:
Mockito.doReturn(true).when(status).isDownloadStarted(Mockito.any(WebDriver.class));
Related
I try to mock same method calls with different collection-arguments.
My problem is that im not getting the correct mocked-answer from Mocked-Call for the input.
Test-Class:
#ExtendWith(SpringExtension.class)
public class CollectionTest {
#MockBean
private Controller c;
#BeforeEach
public void init() {
Collection<String> a = Mockito.anyCollection();
a.add("a");
Mockito.when(c.run(a)).thenReturn("a");
Collection<String> b = Mockito.anyCollection();
b.add("b");
Mockito.when(c.run(b)).thenReturn("b");
}
#Test
public void test() {
assertEquals("a", c.run(Lists.newArrayList("a"))); // DOESNT'WORK!!! Returns "b" but should "a"
assertEquals("b", c.run(Lists.newArrayList("b"))); //
}
}
Controller-Class:
#Service
public class Controller{
public String run(Collection<String> c) {
return "not-mocked";
}
}
I'v got no idea why it doesn't return "a". I tried to change the collection to string but same behaviour.
What are the Steps to do, to get the following behaviour?
#Test
public void test() {
assertEquals("a", c.run(Lists.newArrayList("a"))); // should return "a"
assertEquals("b", c.run(Lists.newArrayList("b"))); // should return "b"
}
Im using Java Mockito "3.1" and Spring, but I think Mockito is the important information here.
Your second call - Mockito.when(c.run(b)).thenReturn("b");
is overruling our first call so Mockito will therefore always return "b".
If you need multiple answers from the same call, you can use the varags variant:
when(c.run(anyCollection())).thenReturn("a", "b");
Now the first call to the controller's run method will return "a" and all subsequent calls will return "b". You can provide as many return results as you want and the last one will be repeated from then on as the answer.
Write two tests will show you the results you are expecting.
You are adding to the same Controller two different results so you get only the last one : Mockito.when(c.run(b)).thenReturn("b");
Normal. The last mocked expected result in your setUp() will stay in memory.
Previous answer was :
You can use something like junit and mockito to test your spring-web-mvc application.
It looks like that :
#WebMvcTest(controllers = UserController.class)
#ActiveProfiles("test")
class UserControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private UserService userService;
private List<User> userList;
#BeforeEach
void setUp() {
this.userList = new ArrayList<>();
this.userList.add(new User(1L, "user1#gmail.com", "pwd1","User1"));
this.userList.add(new User(2L, "user2#gmail.com", "pwd2","User2"));
this.userList.add(new User(3L, "user3#gmail.com", "pwd3","User3"));
}
}
And as an example :
#Test
void shouldFetchAllUsers() throws Exception {
given(userService.findAllUsers()).willReturn(userList);
this.mockMvc.perform(get("/api/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.size()", is(userList.size() )));
}
Example from #see https://medium.com/backend-habit/integrate-junit-and-mockito-unit-testing-for-controller-layer-91bb4099c2a5
I am writing some test code for a processElement function in Apache Flink 1.4:
public class ProcessFunctionClass {
public void processElement(Tuple2<String, String> tuple2, Context context, Collector<Tuple2<String, String>> collector) {
// if the state is empty, start a timer
if (listState.get().iterator().hasNext() == false)
context.timerService().registerEventTimeTimer(1000);
listState.add("someStringToBeStored");
// ...
}
}
public class ProcessFunctionClassTest {
private ProcessFunctionClass processFunctionClass;
#Mock
private ListState<String> listState;
#Before
public void setUp() throws Exception {
processFunctionClass = new ProcessFunctionClass();
}
#Test
public void testProcessElement() {
ListState mockListState = mock(ListState.class);
Iterable mockIterable = mock(Iterable.class);
Iterator mockIterator = mock(Iterator.class);
MockitoAnnotations.initMocks(this);
when(tDPListState.get()).thenReturn(mockIterable);
when(tDPListState.get().iterator()).thenReturn(mockIterator);
when(tDPListState.get().iterator().hasNext()).thenReturn(false);
processFunctionClass.processElement(tuple2, context, collector);
// verify(...)
}
}
When I debug using my IDE, just before I step into the processElement() method, listState is not null and appears to have been mocked successfully, but as soon as I get to listState.get().iterator().hasNext(), listState is null and I get a NullPointerException. What am I doing wrong here?
In ProcessFunctionClass you have a private listState variable.
In your test you create a completely unrelated mockListState variable and set some expectations on it.
For your test to work, you must provide a way (constructor or setter) to set ProcessFunctionClass.listState to desired value (your mocked list state)
On top of that, MockitoAnnotations.initMocks(this); seems to do nothing in your example: you haven't shown us any fields annotated with #Mock or #InjectMocks
Update
You are misusing #Mock annotation.
You should place it in the test class, not in class under test.
When placed in the test class, after a call to initMocks, the filed will be initialized with a mock of an appropriate type.
What you should fo instead:
remove MockitoAnnotations.initMocks(this);, you are creating all the mocks manually.
add a constructor in ProcessFunctionClass
public ProcessFunctionClass(ListState<String> listState) {
this.listState = listState
}
use this constructor in your test
var mockListState = mock(ListState.class);
var processFunctionClass = new ProcessFunctionClass();
I am writing unit test case for a Class
public class CurrentMoreInfoDataProvider implements CurrentMoreInfoInterface.presenterToModel{
private CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
public CurrentMoreInfoDataProvider(CurrentMoreInfoInterface.modelToPresenter modelToPresenter) {
this.modelToPresenter = modelToPresenter;
}
#Override
public void provideData() {
WeatherApiResponsePojo apiWeatherData = WeatherDataSingleton.getInstance().getApiWeatherData();
if(null != apiWeatherData.getCurrently()){
CurrentlyPojo currently = apiWeatherData.getCurrently();
if(null != currently){
populateWeatherData(currently);
}
}
}
public void populateWeatherData(CurrentlyPojo currently) {....}
I want to just use verify method of power mock to test whether populateWeatherData get executed or not. Below is my test case so far.
#RunWith(PowerMockRunner.class)
#PrepareForTest(CurrentMoreInfoDataProvider.class)
public class TestCurrentMoreInfoDataProvider {
private CurrentMoreInfoDataProvider dataProvider;
#Mock
CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
private CurrentlyPojo currentlyPojo = new CurrentlyPojo();
#Test
public void testPopulateWeatherData(){
dataProvider = PowerMockito.spy(new CurrentMoreInfoDataProvider(modelToPresenter));
dataProvider.provideData();
Mockito.verify(dataProvider).populateWeatherData(currentlyPojo);
}
}
If I run this I get null pointer exception in provideData method at
if(null != apiWeatherData.getCurrently()){
How should I provide apiWeatherData to provideData method in that class?
You have to mock WeatherDataSingleton.getInstance().getApiWeatherData() too.
This would be much easier if you would not use static access in general and the Singelton pattern in particular.
I tried mocking it, but how should i provide that mock object to provideData() ?
create a mock of WeatherDataSingleton.
Configure your Test so that this mock is used (by properly using dependency injection or by surrendering to your bad design using Powermock).
configure the mock to return the data:
doReturn(currentlyPojo).when(weatherDataSingletonMock).getApiWeatherData();
This resolves the NPE.
I dont think you need to go for PowerMockito if you apply a simple refactor to your production code:
public class CurrentMoreInfoDataProvider{
#Override
public void provideData() {
WeatherApiResponsePojo apiWeatherData = getApiWeatherData();
if(null != apiWeatherData.getCurrently()){
CurrentlyPojo currently = apiWeatherData.getCurrently();
if(null != currently){
populateWeatherData(currently);
}
}
}
WeatherApiResponsePojo getApiWeatherData(){
return WeatherDataSingleton.getInstance().getApiWeatherData();
}
then in your test expect that new method to return certain object:
#RunWith(MockitoJUnitRunner.class)
public class TestCurrentMoreInfoDataProvider {
private CurrentMoreInfoDataProvider dataProvider;
#Mock
CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
#Mock
WeatherApiResponsePojo apiWeatherDataMock;
private CurrentlyPojo currentlyPojo = new CurrentlyPojo();
#Test
public void testPopulateWeatherData(){
dataProvider = PowerMockito.spy(new CurrentMoreInfoDataProvider(modelToPresenter));
doReturn(apiWeatherDataMock).when(dataProvider).getApiWeatherData();
dataProvider.provideData();
Mockito.verify(dataProvider).populateWeatherData(currentlyPojo);
}
}
Iam using mockito to perform testing and iam very much new to it.
Iam getting a null pointer exception in the Mockito method and in the Onmessage method for the use of a object/variable declared.
The code snippet is as below.
Class A.java
Class A{
#Inject
CheckConnection connection;
public void onMessage(Message m)
{
if(connection.IsInternetavailable==true) //Null pointer is occuring here
{
//Do something with Message
}
else
{
//Do something with Message
}
}
}
Class Atest.java-Mockito Class
Class ATest
{
#InjectMocks
A resource;
#Mock
CheckConnection connection;
#Test
public void shouldProcessMessage() throws JMSException {
// Arrange
final String Type = "MessageType";
final String Body = "MessageBody"
final ActiveMQTextMessage message = new ActiveMQTextMessage();
message.setStringProperty("messageType", Type);
message.setText(Body);
// Act
this.resource.onMessage(message); //This method fails i.e. it gives null pointer exception
}
}
First: the annotation is InjectMocks not InjectMock s is missing
Second: You need to initialize the mocks with this call MockitoAnnotations.initMocks(this); which should be in your set up method or first call in your test method.
Suppose that I have a class like;
public class FooBar {
public int getMethod(List<String> code){
if(code.size() > 100)
throw new Exception;
return 0;
}
}
and I have a test class like this;
#RunWith(PowerMockRunner.class)
#PrepareForTest(FooBar.class)
public class FooBarTest{
FooBar fooBarInstance;
#Before
public void setUp() {
//MockitoAnnotations.initMocks(this);
fooBarInstance = new FooBar();
}
#Test(expected = Exception.class)
public void testGetCorrelationListCodesParameter() {
List<String> codes = Mockito.spy(new ArrayList<String>());
Mockito.doReturn(150).when(codes).size();
fooBarInstance.getMethod(codes);
}
}
How can I make this test method to throw an exception ? I've dealing for hours to do this. Well thanks anyway.
Spying is not needed, mocking is enough. As #David said, also mocking is not needed and not recommended for value object.
Using #Test(expected = Exception.class) has many drawbacks, test can pass when exception is thrown from not expected places. Test is not working but is visible as green.
I prefer BDD style testing with catch-exception.
Reasons for using catch-exceptions
(...) in comparison to the use of try/catch blocks.
The test is more concise and easier to read.
The test cannot be corrupted by a missing assertion. Assume you forgot to type fail() behind the method call that is expected to throw an exception.
(...) in comparison to test runner-specific mechanisms that catch and verify exceptions.
A single test can verify more than one thrown exception.
The test can verify the properties of the thrown exception after the exception is caught.
The test can specify by which method call the exception must be thrown.
The test does not depend on a specific test runner (JUnit4, TestNG).
import static com.googlecode.catchexception.CatchException.caughtException;
import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.*;
public class FooBarTest {
FooBar sut = new FooBar(); // System Under Test
#Test
public void shouldThrowExceptionWhenListHasTooManyElements() {
when(sut).getMethod(listWithSize(150));
then(caughtException()).isInstanceOf(Exception.class);
}
private List<String> listWithSize(int size) {
return new ArrayList<String>(Arrays.asList(new String[size]));
}
}
Full working code for this test: https://gist.github.com/mariuszs/8543918
Not recommended solution with expected and mocking.
#RunWith(MockitoJUnitRunner.class)
public class FooBarTest {
#Mock
List<String> codes;
FooBar fooBarInstance = new FooBar();
#Test(expected = Exception.class)
public void shouldThrowExceptionWhenListHasTooManyElements() throws Exception {
when(codes.size()).thenReturn(150);
fooBarInstance.getMethod(codes);
}
}
A list is a value object. It's not something we should mock. You can write this whole test without mocking anything, if you're prepared to build a list that has a size in excess of 100.
Also, I prefer to use JUnit's ExpectedException mechanism, because it lets you check which line of the test method threw the exception. This is better than passing an argument to the #Test annotation, which only lets you check that the exception was thrown somewhere within the method.
public class FooBarTest {
#Rule
public ExpectedException exceptionRule = ExpectedException.none();
private FooBar toTest = new FooBar();
#Test
public void getMethodThrowsException_whenListHasTooManyElements() {
List<String> listWith101Elements =
new ArrayList<String>(Arrays.asList(new String[101]));
exceptionRule.expect(Exception.class);
toTest.getMethod(listWith101Elements);
}
}