Kotlin Testing API Call - unit-testing

I want to test an API call I make - where I use the Retrofit2 framework for.
My code is the following:
API Utilities File:
package com.example.nsi_prediction.API
import com.example.nsi_prediction.API.RetrofitClient.getClient
object ApiUtils {
/**
* Defines the used utilities for the Retrofit Client
*/
const val BASE_URL = "http://10.0.2.2:8080/"
fun getAPIService(): APIService {
return getClient(BASE_URL)!!.create(
APIService::class.java)
}
}
Retrofit Client Object
object RetrofitClient {
/**
* Initializes the retrofit Client
*/
private var retrofit: Retrofit? = null;
fun getClient(baseUrl: String?): Retrofit? {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit
}
}
API Service File:
interface APIService {
/**
* All specific API calls are defined here
*/
#POST("/api/v1/gps")
#Headers(
"Accept: application/json",
"Content-type:application/json"
)
fun sendGPS(#Body GPS: GPS): Call<GPS>
}
I have written my test like this:
#RunWith(JUnit4::class)
class RequestTest {
#InjectMocks
lateinit var RetrofitClient: RetrofitClient;
#InjectMocks
lateinit var gps_model: GPS;
#Mock
lateinit var APIs: APIService;
#InjectMocks
lateinit var ApiUtils: ApiUtils;
#Before
fun setUp() {
MockitoAnnotations.initMocks(this)
Mockito.`when`<Any>(APIs.sendGPS(gps_model).execute().message())
.thenReturn("{'x': '1.4'}")
}
#Test
fun setGitHubTaskTest_ReturnsTrue() {
assertThat(APIs.sendGPS(gps_model).execute().message(), containsString("1.4"))
}
}
But when I run the test I get a Null Pointer Exception:
java.lang.NullPointerException
at com.example.nsi_prediction.RequestTest.setUp(RequestTest.kt:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
I want to jsut test if the logic in which the different files talk to each other works. How can I test my API Call functions correctly?

Related

how to handle CriteriaBuilder and predicates in junit mockito testcase

Impl.java
------------------------------------------------------------------
public List<SearchDTO> findByCriteria(SearchCriteriaDTO SearchCriteriaDTO) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Search> query = builder.createQuery(Search.class);
Root<Search> repls = query.from(Search.class);
final int QUERY_LIMIT = Integer.parseInt(queryLimit);
List<UUID> statusIds = SearchCriteriaDTO.getStatusIds();
if (statusIds != null && !statusIds.isEmpty()) {
predicates.add(builder.and(repl.get("statusId").in(statusIds)));
}
-----------------------------
below is the test class for impl class.
impltest.java
---------------------------
//mocking the services.
#Mock
private SearchMapper SearchMapper;
#Mock
private SearchRepository SearchRepository;
#Mock
private CriteriaBuilder criteriaBuilder;
#Mock
private Root root;
#Mock
private EntityManager entityManager;
#Rule
public ExpectedException thrown = ExpectedException.none();
#Mock
CriteriaQuery<Search> criteriaQuery;
#Mock
Root<UUID> statusId;
#Mock
Path<String> path;
#Mock
Expression expr;
#Mock
Predicate predicate;
#Mock
TypedQuery<Member> querymem;
#Mock
Root<Search> rSearchRootMock;
#InjectMocks
private SearchServiceImpl SearchService;
#Value("${query.limit}")
String queryLimit;
#Before
public void init() {
MockitoAnnotations.initMocks(SearchService);
SearchRootMock = mock(Root.class);
}
#Test
public void test_findby_criteria() {
hen(entityManager.getCriteriaBuilder()).thenReturn(criteriaBuilder); when(criteriaBuilder.createQuery(Search.class)).thenReturn(criteriaQuery);
when(criteriaQuery.from(Search.class)).thenReturn(SearchRootMock);
Path statusIdMock = mock(Path.class);
//when(Integer.parseInt(queryLimit)).thenReturn(1);
String status = "statusId";
Expression<String> doublePath = root.get(status);
when(root.get((status))).thenReturn((Path) doublePath);
when(criteriaBuilder.upper(root.<String>get(status))).thenReturn(expr);
when(criteriaBuilder.equal(expr,status.toUpperCase())).thenReturn(predicate);
when(root.get("statusId")).thenReturn(path);
when(this.SearchService.findByCriteria(SearchCriteriaDTO)).thenReturn(Searches);
here i am trying to mock the predicate but getting null point exception due to root.get("statusId").
please let me know how to mock it.
here are the issues
how to handle and mock the #Value("${query.limit}") where i am reading limit from application properties file.
getting null point exception in predicate line.
predicates.add(builder.and(repl.get("statusId").in(statusIds)));
not able to map the column name here for repl.get("statusId") where getting null.
please help me to solve this problem.Thanks
below is the error
java.lang.NumberFormatException: For input string: "${query.limit}"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:569)
at java.lang.Integer.parseInt(Integer.java:615)
at com.capturerx.cumulus4.replenishment.impl.ReplenishmentSearchServiceImplTest.test_findby_criteria_for_success(ReplenishmentSearchServiceImplTest.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
getting java.lang.NullPointerException at line
query.select(replenishments).where(predicates.toArray(new Predicate[predicates.size()]));

how to use Mockito when in kotin to mock method call and return mock value?

Can someone help me figure out why my kotlin variable that i mocked and named "repo" is still executing a method im telling mockito to mock ? let me show you what i mean:
i have a simple usecase class that looks like this:
class WeatherDetailsPresenter #Inject constructor(var getCurrentWeatherWithForecastUsecase: GetCurrentWithForcastedWeatherUsecase) : BaseMvpPresenter<WeatherDetailsView>() {
fun presentCurrentAndForcastedWeather(country: String?) {
with{getCurrentWeatherWithForecastUsecase) {
this.countyName = country
execute(object : DefaultSubscriber<Pair<CurrentWeatherModel, ForecastedWeatherModel>>() {
override fun onSubscribe(d: Disposable) {
super.onSubscribe(d)
showLoading(true)
}
override fun onNext(t: Pair<CurrentWeatherModel, ForecastedWeatherModel>) {
super.onNext(t)
view?.showCurrentWeather(t.first)
}
override fun onComplete() {
super.onComplete()
showLoading(false)
}
})
}
}
}
all it does is you pass it a country name and it gets the average weather for that country and also 7 day forecast. no big deal. it puts it all together in a pair and updates the view (MVP). it fetches the data from another class called a WeatherDataRepository who's implementation is not import as long as it returns data we dont care.
let me show you what the getCurrentWeatherWithForecastUsecase class actgually looks like:
class GetCurrentWithForcastedWeatherUsecase #Inject constructor(var weatherRepo: WeatherDataRepository) : BaseUseCase() {
var countyName: String? = null
override fun buildUseCaseObservable(): Observable<Pair<CurrentWeatherModel, ForecastedWeatherModel>> {
return weatherRepo.fetchCurrentWeatherWith7dayForcast(countyName.toString())
}
}
//see its easy it just takes a weatherRepository and asked it to fetch the results. i send that back to the caller who will display it.
now that you know what this simple method does let me show you what i am trying to test. I wish to simply test that the currentweather was shown. so really in the end i want to test that view?.showCurrentWeather(t.first) was called.
Here is my junit test case:
class WeatherDetailsPresenterTest {
lateinit var usecase: GetCurrentWithForcastedWeatherUsecase
#Mock
lateinit var repo: WeatherDataRepository
#Mock
lateinit var view: WeatherDetailsView
lateinit var presenter: WeatherDetailsPresenter
#Before
fun setUp() {
MockitoAnnotations.initMocks(this)
usecase = GetCurrentWithForcastedWeatherUsecase(repo)
presenter = WeatherDetailsPresenter(usecase)
}
#Test
fun testCurrentWeatherScreenAppears() {
//arrange
//WHY IS THIS MOCK NOT WORKING ??
Mockito.`when`(repo.fetchCurrentWeatherWith7dayForcast(anyString())).thenReturn(Observable.just(Pair<CurrentWeatherModel, ForecastedWeatherModel>(ArgumentMatchers.any(CurrentWeatherModel::class.java),ArgumentMatchers.any(ForecastedWeatherModel::class.java))))
//act
val testSubscriber = TestObserver<Pair<CurrentWeatherModel, ForecastedWeatherModel>>()
usecase.execute(testSubscriber)
//assert
testSubscriber.assertNoErrors()
testSubscriber.assertSubscribed()
testSubscriber.assertValue(Pair(ArgumentMatchers.any(), ArgumentMatchers.any()))
testSubscriber.assertComplete()
Mockito.verify(view,times(1)).showCurrentWeather(any())
}
}
The unit tests compiles and runs. the issue is the repository call is actually calling fetchCurrentWeatherWith7dayForcast instead of just returning the mock response.
here is the error when i run the test cases (failure error):
java.lang.NullPointerException
at me.org.myweatherapp.data.repositories.WeatherDataRepository.fetchCurrentWeatherWith7dayForcast(WeatherDataRepository.kt:17)
at me.org.myweatherapp.presentation.view.mvp.mainScreen.fragments.weatherdetails.WeatherDetailsPresenterTest.testCurrentWeatherScreenAppears(WeatherDetailsPresenterTest.kt:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
you should not need to see the repository code but i'll show it anyway:
class WeatherDataRepository #Inject constructor(val retrofit: Retrofit){
//THIS SHOULD NEVER BE CALLED, SINCE IM MOCKING IT, BUT ITS CALLED, WHY??
fun fetchCurrentWeatherWith7dayForcast(countyName: String): Observable<Pair<CurrentWeatherModel, ForecastedWeatherModel>> {
val weatherApiService = retrofit.create(WeatherApi::class.java)
return weatherApiService.getCurrentWeather(countyName)
.zipWith<ForecastedWeatherModel,Pair<CurrentWeatherModel, ForecastedWeatherModel>>(weatherApiService.getForecastedWeather(countyName)
.map{model-> model.forecast?.forecastday?.forEach { it?.dayName= getDay(it?.date.toString())}; model }
, BiFunction { t1, t2 -> Pair(t1,t2) })
}}
i am already annotating the repo to be mocked and then in the setup i initialized all mocks, so the only thing i can think of is im not using the Mockito.when command the right away ? any help appreciated.
UPDATE:
HERE IS THE ENTIRE STACK TRACE OF THE FAILURE:
"/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java" -ea -Didea.test.cyclic.buffer.size=1048576 -Didea.launcher.port=57805 "-Didea.launcher.bin.path=/Applications/Android Studio.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/Contents/lib/idea_rt.jar:/Applications/Android Studio.app/Contents/plugins/junit/lib/junit-rt.jar:/Applications/Android Studio.app/Contents/plugins/junit/lib/junit5-rt.jar:/Users/me/Library/Android/sdk/platforms/android-27/data/res:/Users/me/Documents/mystuff/weatherappdemo/app/build/intermediates/classes/prod/debug:/Users/me/Library/Android/sdk/extras/m2repository/com/android/support/constraint/constraint-layout-solver/1.0.2/constraint-layout-solver-1.0.2.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-v4-27.1.1.aar/8c528b77506492992ca9cefd2fbe3fc1/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.2.21/88bfff5aa470143a83b0bc5ec00c0be8cabd7cad/kotlin-stdlib-jdk7-1.2.21.jar:/Users/me/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.2.41/e4d6728a4fa55dbfb510aeea25c072c7c51d94/kotlin-reflect-1.2.41.jar:/Users/me/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common-java8/1.0.0/a7458929c2f84a8a59b6b4da631a36f07091cf79/common-java8-1.0.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-media-compat-27.1.1.aar/8c1ab73749282027c9894ed4f6387856/res:/Users/me/.gradle/caches/transforms-1/files-1.1/support-media-compat-27.1.1.aar/8c1ab73749282027c9894ed4f6387856/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.bouncycastle/bcprov-jdk15on/1.50/be504b4901d75cbe129a178f5830e6c358ec214c/bcprov-jdk15on-1.50.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/stetho-1.5.0.aar/f176def4c2ceb952e3ab306a7d56241a/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/rules-1.0.1.aar/88459f9e0846eb9599bad2e0efbab6bb/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-auth-base-license-11.8.0.aar/1f271bdf7747c7247ce3e2d7b7a8ff8e/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-basement-license-11.8.0.aar/9ae67be5ece95255b9bcca7d0378d2b4/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-iid-11.8.0.aar/951a9ce1737846087ee53aaecfb671c0/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-fragment-27.1.1.aar/227f5a73c4224f35e666b27741d51529/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/retrofit/2.3.0/bcacde6a8ccedcc56c127403d26b76072fe6214d/retrofit-2.3.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/runtime-1.1.0.aar/506f9955d304b32a4564c4b84422fea4/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/design-27.1.1.aar/4f85b6a28d4b1cf224a5e6cb1d4dbc66/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/design-27.1.1.aar/4f85b6a28d4b1cf224a5e6cb1d4dbc66/res:/Users/me/.gradle/caches/transforms-1/files-1.1/runtime-1.0.0.aar/7af827a5af0341c7eceb2a9ffa27a39e/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/multidex-instrumentation-1.0.2.aar/d67f47874da4e87ad02796a65dc73f61/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-config-11.8.0.aar/bc62621a53fdb88540784b9828b13fde/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/23e568de9f4f0daff9b5d756af53aa07/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/23e568de9f4f0daff9b5d756af53aa07/res:/Users/me/.gradle/caches/modules-2/files-2.1/org.greenrobot/eventbus/3.0.0/ddd99896e9569eaababbe81b35d80e1b91c4ad85/eventbus-3.0.0.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/3.8.0/5a11f020cce2d11eb71ba916700600e18c4547e7/okhttp-3.8.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-analytics-impl-11.8.0.aar/5b4765afdec874f91c04f5abe56e5275/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/android.arch.persistence.room/common/1.0.0/1cbd3ddc566125293b13af5c0a65bc015476e83c/common-1.0.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/runtime-1.1.0.aar/1fb10be0704f03034b6aa2314ccf3e4d/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/transition-27.1.1.aar/91b8eaec16a28ef6b3781544873a983d/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/transition-27.1.1.aar/91b8eaec16a28ef6b3781544873a983d/res:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-auth-base-11.8.0.aar/882aae6015201ef880d7ddb46766a289/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/butterknife-8.8.1.aar/cf0409e6eb4d8f95c289b322c09c7470/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/fbcore-1.3.0.aar/881eb80147e1a600eb4fdd7ca2ca248e/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-common-11.8.0.aar/7840ba4061070f9ac09a6db65e355818/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-analytics-impl-license-11.8.0.aar/a56e270bd3ae1a384d54e6bd9a48d02d/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/uiautomator-v18-2.1.0.aar/9b94013d0aeaac82611731b234cecc7b/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-compat-27.1.1.aar/8da86b1dff1f0160efbb1b9cd1b03a26/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-compat-27.1.1.aar/8da86b1dff1f0160efbb1b9cd1b03a26/res:/Users/me/.gradle/caches/transforms-1/files-1.1/espresso-contrib-3.0.1.aar/775bf13abb0c730effcf8406c262c9f3/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/viewmodel-1.1.0.aar/1decb5c20af306b59139842edceb0bf7/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.reactivestreams/reactive-streams/1.0.0/14b8c877d98005ba3941c9257cfe09f6ed0e0d74/reactive-streams-1.0.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-core-11.8.0.aar/40ccc15d85cb93820d69a9a52ee41860/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife-annotations/8.8.1/bc373fb6bc7bca3035041b924f158fd2b946ee8d/butterknife-annotations-8.8.1.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-android-extensions-runtime/1.2.41/c1fd16a8b0be2f6c95dd43e1560d5b86ff742fdc/kotlin-android-extensions-runtime-1.2.41.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/spots-dialog-0.7.aar/d5614913769f6b38243111c590a8482f/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/spots-dialog-0.7.aar/d5614913769f6b38243111c590a8482f/res:/Users/me/.gradle/caches/transforms-1/files-1.1/support-vector-drawable-27.1.1.aar/5eb343d801e7f29a5d223861abe3b6fc/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/stetho-okhttp3-1.5.0.aar/519dbbb66efddad4a4bfae9c6e76718d/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-iid-license-11.8.0.aar/423297131a354e0bfbd7103a38722964/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.github.ihsanbal/LoggingInterceptor/2.0.2/e0230eb518409058f04f1be8e356d9dfd9d7126b/LoggingInterceptor-2.0.2.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-core-utils-27.1.1.aar/10757417e97a4e5d394b007d55ed39df/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-basement-11.8.0.aar/96b45c45c9e7d0359214ab8878e5b137/res:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-basement-11.8.0.aar/96b45c45c9e7d0359214ab8878e5b137/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.2.41/7e34f009642702250bccd9e5255866f408962a05/kotlin-stdlib-1.2.41.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/2.0.1/516c03b21d50a644d538de0f0369c620989cd8f0/jsr305-2.0.1.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/imagepipeline-base-1.3.0.aar/a7e27f7f6f4d580103459e14d4d91132/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-base-license-11.8.0.aar/0e66bd26413f298ad4b21d093883f138/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/core-ktx-0.1.aar/b15ebaf7972ab87fc408b81f8cd9b7f8/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/adapter-rxjava2/2.3.0/f436637f9500ab5b8bc32afe556373180894b4a5/adapter-rxjava2-2.3.0.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.9/75a739e59d7ede2f7f425f369955bdd1c2ac122b/dagger-2.9.jar:/Users/me/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy/1.6.14/871c3e49dc6183d0d361601c2f1d11abb1a6b48c/byte-buddy-1.6.14.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/imagepipeline-1.3.0.aar/f7d55bb54a7fcb0dc52ca620f3cb3390/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/rxbinding-2.0.0.aar/71b2449f24db0bbe295118e38c3b099c/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common/1.1.0/edf3f7bfb84a7521d0599efa3b0113a0ee90f85/common-1.1.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/drawee-1.3.0.aar/0d2fd7b15bc817f241bd45a7af724235/res:/Users/me/.gradle/caches/transforms-1/files-1.1/drawee-1.3.0.aar/0d2fd7b15bc817f241bd45a7af724235/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.objenesis/objenesis/2.5/612ecb799912ccf77cba9b3ed8c813da086076e9/objenesis-2.5.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.7/751f548c85fa49f330cecbb1875893f971b33c4e/gson-2.7.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.2.41/9e7a6f582de73d9cdc6c56ef4e23604a0ee55768/kotlin-stdlib-jre7-1.2.41.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/logging-interceptor/3.8.0/f765f004f3e201bd6ad0904266e605d7fb776d5/logging-interceptor-3.8.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/recyclerview-v7-27.1.1.aar/5c32c514912225f8996a860cdae759cb/res:/Users/me/.gradle/caches/transforms-1/files-1.1/recyclerview-v7-27.1.1.aar/5c32c514912225f8996a860cdae759cb/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/multidex-1.0.2.aar/3d385f486b764139c13b624fee0b32c0/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-core-ui-27.1.1.aar/10a6e827fb24388f3d393ee95b15305c/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/support-core-ui-27.1.1.aar/10a6e827fb24388f3d393ee95b15305c/res:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-tasks-license-11.8.0.aar/f8cc3f0ba924aff3c7d5cc7c9c56f7e9/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/idling-concurrent-3.0.1.aar/bf368765eb5955d1a89d234f6c5669ee/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/rxjava2-1.0.0.aar/406d1a35f2fb9c28ac1c637df15d49db/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/converter-gson/2.3.0/9e09011e9767bb76b5e27c9b8223476b93b14631/converter-gson-2.3.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-messaging-license-11.8.0.aar/0c9522887d98bb37f93e8694bc9cab09/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-config-license-11.8.0.aar/6602b35b3e55aebb6ac4665e9872b5fc/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/io.reactivex.rxjava2/rxjava/2.1.1/99895d4dc6d79efbb74360f13c556d95533ad8f8/rxjava-2.1.1.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-auth-api-phone-license-11.8.0.aar/f3df85960ad3eeb19f7be4ce902b978a/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/db-framework-1.0.0.aar/796c04fce9221c438948f9c68e14c88c/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/viewstate-2.0.1.aar/bf016c65c3e0c7dcafda5281f41b4e81/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/db-1.0.0.aar/81d8f63860272b7c43a6709748e52ee9/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/io.reactivex.rxjava2/rxjava/2.1.7/8c6d3f76a0b8ed49e9d49a5af9c80c5fc2091677/rxjava-2.1.7.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-messaging-11.8.0.aar/fbcba383734b49591176a7772066d087/res:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-messaging-11.8.0.aar/fbcba383734b49591176a7772066d087/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-common-license-11.8.0.aar/a853cc000b4a9e97a1e8cb8510bbde3a/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-auth-11.8.0.aar/e8a403bb2bc41b0978151644434be336/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/runner-1.0.1.aar/bc61594971ebf029997add3d9e064acb/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/timber-4.5.1.aar/ed168ba0862d519a47bca16bf4dac2df/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.android.support/support-annotations/27.1.1/39ded76b5e1ce1c5b2688e1d25cdc20ecee32007/support-annotations-27.1.1.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/animated-vector-drawable-27.1.1.aar/e91ef01a13292102a7a45e6e1080e1fb/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-analytics-license-11.8.0.aar/6b229f59f2b7a192f74a9c7d5a33dfe2/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-auth-api-phone-11.8.0.aar/a76aa8978d4a42b84287b4c62555d7a0/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-analytics-11.8.0.aar/9dfc8e29830fdadd2e7d25b1baa19671/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.parse.bolts/bolts-tasks/1.4.0/d85884acf6810a3bbbecb587f239005cbc846dc4/bolts-tasks-1.4.0.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.13.0/a9283170b7305c8d92d25aff02a6ab7e45d06cbe/okio-1.13.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/fresco-1.3.0.aar/db4a2dd4f4c2cab75bf3453e6639ed58/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/rx2-idler-0.9.0.aar/2592289841865b391355f5d4fc368251/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/espresso-intents-3.0.1.aar/eb5beafb4e6532e880eb8af7a315b9f6/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.reactivestreams/reactive-streams/1.0.1/1b1c911686eb40179219466e6a59b634b9d7a748/reactive-streams-1.0.1.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/mvp-2.0.1.aar/f0614328bd1e1100af13886a9dcde777/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/mvp-2.0.1.aar/f0614328bd1e1100af13886a9dcde777/res:/Users/me/.gradle/caches/transforms-1/files-1.1/espresso-core-3.0.1.aar/3d7b614004a6eaa78227a35fd3cee256/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/espresso-web-3.0.1.aar/cf8ebc9ea102e614f709045983fb32a7/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/rxandroid-2.0.1.aar/5516ddab631416f22f025eb065849949/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.0.2.aar/3eb445c5139d11809f5142c08a3b669a/res:/Users/me/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.0.2.aar/3eb445c5139d11809f5142c08a3b669a/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-base-11.8.0.aar/6022e015ee3a8def24bc31049a72d6b5/res:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-base-11.8.0.aar/6022e015ee3a8def24bc31049a72d6b5/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/espresso-idling-resource-3.0.1.aar/12c9fd22796fd8b15ccaf8884ae23c20/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.2.21/86407aed2dc197bd5f61d16e759c4ff43678732a/kotlin-stdlib-jdk8-1.2.21.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.rubylichtenstein/rxtest/1.0.7/43a4d1a2b4dcc14c669f4be81680a4e4b7d3dd1e/rxtest-1.0.7.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.picasso/picasso/2.5.2/7446d06ec8d4f7ffcc53f1da37c95f200dcb9387/picasso-2.5.2.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/livedata-core-1.1.0.aar/518c06f36c54349dedb9b4d7d98fdde5/jars/classes.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-tasks-11.8.0.aar/c516e10968cea0d1c7a34bf5a433c591/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/mockwebserver/3.8.0/6bcc6566897ffae93c62e53ff8e8e71af18d7593/mockwebserver-3.8.0.jar:/Users/me/.gradle/caches/modules-2/files-2.1/com.hannesdorfmann.mosby/mvp-common/2.0.1/d75c9c5577143f3cf3fd63f61526a551f910b56f/mvp-common-2.0.1.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-auth-11.8.0.aar/860f44f092aa569d6e12cc2a8b2f1f16/res:/Users/me/.gradle/caches/transforms-1/files-1.1/play-services-auth-11.8.0.aar/860f44f092aa569d6e12cc2a8b2f1f16/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/android.arch.core/common/1.1.0/8007981f7d7540d89cd18471b8e5dcd2b4f99167/common-1.1.0.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/timberkt-1.3.0.aar/3061f0b036f5136e670a5c16d103a232/jars/classes.jar:/Users/me/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.6.14/ba1e5ba3a84fb2fbf2f4de9138df19665eec4d59/byte-buddy-agent-1.6.14.jar:/Users/me/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-core/2.8.9/1afb35b2d77d40567756c379e54c18da3574a96e/mockito-core-2.8.9.jar:/Users/me/.gradle/caches/transforms-1/files-1.1/firebase-auth-license-11.8.0.aar/c11a9a832d941e454c91804c30c3b8e5/jars/classes.jar:/Users/me/Documents/mystuff/weatherappdemo/app/build/intermediates/sourceFolderJavaResources/test/prod/debug:/Users/me/Documents/mystuff/weatherappdemo/app/build/tmp/kotlin-classes/prodDebugUnitTest:/Users/me/Documents/mystuff/weatherappdemo/app/build/tmp/kapt3/classes/prodDebugUnitTest:/Users/me/Documents/mystuff/weatherappdemo/app/build/intermediates/sourceFolderJavaResources/prod/debug:/Users/me/Documents/mystuff/weatherappdemo/app/build/tmp/kapt3/classes/prodDebug:/Users/me/Documents/mystuff/weatherappdemo/app/build/tmp/kotlin-classes/prodDebug:/Users/me/Documents/mystuff/weatherappdemo/app/build/generated/mockable-android-27.v3.jar" com.intellij.rt.execution.application.AppMainV2 com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 me.org.weatherapp.presentation.view.mvp.mainScreen.fragments.weatherdetails.WeatherDetailsPresenterTest
java.lang.NullPointerException
at me.org.weatherapp.data.repositories.WeatherDataRepository.fetchCurrentWeatherWith7dayForcast(WeatherDataRepository.kt:17)
at me.org.weatherapp.presentation.view.mvp.mainScreen.fragments.weatherdetails.WeatherDetailsPresenterTest.testCurrentWeatherScreenAppears(WeatherDetailsPresenterTest.kt:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:78)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
I finally saw my issue. i was making it too complicated. First the presenter should subscribe to the observable so my baseUseCase should look like this instead:
public abstract class BaseUseCase {
protected abstract Observable buildUseCaseObservable();
#SuppressWarnings("unchecked")
public Observable retrieveUseCaseObservable(){
return this.buildUseCaseObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}
then the actual test case simply mocks the usecase and view and tests the presenter and it all seems work now:
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.BDDMockito
import org.mockito.BDDMockito.given
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.runners.MockitoJUnitRunner
#RunWith(MockitoJUnitRunner::class)
class WeatherDetailsPresenterTest {
#Mock
lateinit var usecase: GetCurrentWithForcastedWeatherUsecase
#Mock
lateinit var view: WeatherDetailsView
lateinit var presenter: WeatherDetailsPresenter
#Before
fun setUp() {
MockitoAnnotations.initMocks(this)
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
presenter = WeatherDetailsPresenter(usecase)
presenter.attachView(view)
}
#Test
fun testCurrentWeatherScreenAppears() {
//arrange
given(usecase.retrieveUseCaseObservable()).willReturn(Observable.just(Pair(CurrentWeatherModel(), ForecastedWeatherModel())))
//act
presenter.presentCurrentAndForcastedWeather("canada")
//assert
BDDMockito.verify(view, BDDMockito.times(1)).showCurrentWeather(any(CurrentWeatherModel::class.java)?:CurrentWeatherModel())
}
}
the elvis operation is to satisfy kotlin
when we make the presenter call note that now i am subscribing from within the presenter:
fun presentCurrentAndForcastedWeather(country: String?) {
getCurrentWeatherWithForecastUsecase.takeUnless { country?.isBlank() == true }?.apply {
this.countyName = country
retrieveUseCaseObservable().subscribe(object : DefaultSubscriber<Pair<CurrentWeatherModel, ForecastedWeatherModel>>() {
override fun onSubscribe(d: Disposable) {
super.onSubscribe(d)
showLoading(true)
}
override fun onNext(t: Pair<CurrentWeatherModel, ForecastedWeatherModel>) {
super.onNext(t)
view?.showCurrentWeather(t.first)
view?.showForcastWeather(t.second)
}
override fun onError(e: Throwable) {
super.onError(e)
showError { this#WeatherDetailsPresenter.presentCurrentAndForcastedWeather(country) }
}
override fun onComplete() {
super.onComplete()
showLoading(false)
}
})
} ?: run { view?.showCountryUnavailable() }
}
i also added RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
to tell the rxJava system to run on the current thread, since everythings mocked anyway.

Apache Camel Mock ProducerTemplate Endpoint

I want to mock the mail sending not to send mail in unit testing.
My code is below:
#Component("utilityRoutes")
public class UtilityRoutes extends RouteBuilder {
#Override
public void configure() throws Exception {
from("seda:sendEmail")
.routeId("utilityRoutes")
.setHeader("from", simple("{{email.from}}"))
.setHeader("contentType", constant("text/plain;charset=UTF-8"))
.choice()
.when(header(Constants.HEADER_EMAIL_TARGET).isEqualTo("AAA"))
.setHeader("to", simple("{{recipients-a}}"))
.when(header(Constants.HEADER_EMAIL_TARGET).isEqualTo("BBB"))
.setHeader("to", simple("{{recipients-b}}"))
.end()
.to("{{email.url}}")
.id("emailUrl");
}
}
My Test Case is:
#RunWith(CamelSpringBootRunner.class)
#SpringBootTest
#TestPropertySource(locations = "classpath:application.properties")
#ContextConfiguration(classes = { RailMLExport.class })
#DirtiesContext
public class UtilityRoutesTest extends CamelTestSupport {
#Autowired
CamelContext camelContext;
#Produce(uri = "seda:sendEmail")
ProducerTemplate producerTemplate;
#EndpointInject(uri="mock:emailEndpoint")
MockEndpoint mailEndpoint;
#Override
public boolean isUseAdviceWith() {
return true;
}
#Override
public String isMockEndpoints() {
return "*";
}
#Test
public void testSendAndReceiveMail() throws Exception {
camelContext.getRouteDefinition("utilityRoutes").adviceWith(camelContext, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
weaveById("emailUrl").after().to("mock:emailEndpoint");
}
}
);
camelContext.start();
Collection<Endpoint> endpoints = camelContext.getEndpoints();
for (Endpoint endpoint : endpoints) {
System.err.println(endpoint.getEndpointUri());
}
mailEndpoint.expectedMessageCount(1);
mailEndpoint.expectedBodyReceived();
Map<String,Object> headers = new HashMap<>();
headers.put(Constants.HEADER_EMAIL_TARGET,"AAA");
headers.put(Constants.HEADER_EMAIL_SUBJECT, "CCC");
producerTemplate.requestBodyAndHeaders("seda:sendEmail", "test", headers);
mailEndpoint.assertIsSatisfied();
}
}
I give error as follows.
java.lang.IllegalStateException: ProducerTemplate has not been started
at org.apache.camel.impl.DefaultProducerTemplate.getProducerCache(DefaultProducerTemplate.java:689)
at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:148)
at org.apache.camel.impl.DefaultProducerTemplate.sendBodyAndHeaders(DefaultProducerTemplate.java:267)
at org.apache.camel.impl.DefaultProducerTemplate.requestBodyAndHeaders(DefaultProducerTemplate.java:317)
at org.apache.camel.impl.DefaultProducerTemplate.requestBodyAndHeaders(DefaultProducerTemplate.java:313)
at fi.vr.h.ivu.integration.railmlexport.routes.UtilityRoutesTest.testSendAndReceiveMail(UtilityRoutesTest.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Either overwrite isMockEndpointsAndSkip or use adviceWith as you mentioned and skip it in that AdviceWithRoute. You can even intercept your exchange and call skipSendToOriginalEndpoint from there. Different possible ways to accomplish what you want.
A further note: You probably shouldn't use "*" in isMockEndpoints (or isMockEndpointsAndSkip), except you want to mock every route. Just mention the routes you really want to mock. This way it is more clear for other programmers watching your code what you really are mocking and what not.

Getting java.lang.NullPointerException for mvc.perform()

I am new to unit testing in spring boot. I am trying to test a service and have used Mockito for it. When I do mvc.perform() I get a null value. I have used when() to specify what to return. But not sure why it fails. Please provide some valuable inputs. Here are fe snippets:
#Test
public void testAll() throws Exception {
/*Mockito.when(sensorDao.findAll()).thenReturn((Iterable<Sensor>) s2);
assertEquals(200,expect().statusCode(200));*/
Collection<Sensor>list = getEntityListStubData();
when(sensorserviceimpl.findAll()).thenReturn(list);
when(sensorService.findAll()).thenReturn(list);
when(sensorDao.findAll()).thenReturn(list);
String uri="/sensor";
//System.out.print("gfnjhkjjhhg");
System.out.println("Helllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloooooooooooooooooooooooooooooooooooooooooooo");
System.out.println(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON));
MvcResult result = mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON)).andReturn();
String content = result.getResponse().getContentAsString();
int status = result.getResponse().getStatus();
}
Here is the output:
2017-08-18 19:11:45.030 INFO 21424 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test context [DefaultTestContext#35083305 testClass = SensorServiceStandaloneApplicationTests, testInstance = com.bny.sr.sensorservicestandalone.SensorServiceStandaloneApplicationTests#482cd91f, testMethod = testAll#SensorServiceStandaloneApplicationTests, testException = java.lang.NullPointerException, mergedContextConfiguration = [WebMergedContextConfiguration#8e0379d testClass = SensorServiceStandaloneApplicationTests, locations = '{}', classes = '{class com.bny.sr.sensorservicestandalone.SensorServiceStandaloneApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{eureka.client.enabled:false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}', contextCustomizers = set[org.springframework.boot.test.context.SpringBootTestContextCustomizer#167fdd33, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#53f65459, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#74650e52, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#80503], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]].
java.lang.NullPointerException
at com.bny.sr.sensorservicestandalone.SensorServiceStandaloneApplicationTests.testAll(SensorServiceStandaloneApplicationTests.java:163)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
2017-08-18 19:11:45.046 INFO 21424 --- [ Thread-5] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#5386659f: startup date [Fri Aug 18 19:11:34 IST 2017]; root of context hierarchy
2017-08-18 19:11:45.054 INFO 21424 --- [ Thread-5] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
Process finished with exit code -1
Here is the debug result:
Debug results
Since spring-boot 1.4.0 you can use #WebMvcTest which will auto-configure MockMvc. Also, use #MockBean to mock any dependency in your controller.
#RunWith(SpringRunner.class)
#WebMvcTest(MyController.class)
public class MyControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private SensorDao sensorDao;
}
#AutoConfigureMockMvc, will also do the trick

I am new to JUnit Testing.I am unable to write successful test cases and the test Case I create is returning a nullpointer exception

I am trying to write test cases for an endpoint controller for the following controllers
#RestController
#RequestMapping("/agent/")
public class AgentRestController extends BaseRestController {
#RequestMapping(value = "/log/{revisionId}/", method = RequestMethod.PUT)
public ResponseEntity<?> log(#PathVariable("revisionId") String revisionId, #RequestBody LogMessage message) {
ConfigurationRevision cr = configurationRevisionRepository.findOne(revisionId);
BackupLog log = new BackupLog(message);
log.setRevision(cr);
backupLogRepository.save(log);
return new ResponseEntity<>(HttpStatus.CREATED);
}
#RequestMapping("/config")
#ResponseBody
public AgentConfig getConfiguration(HttpServletRequest request) {
AgentConfig cfg = getAgentConfigByIP(request.getRemoteAddr());
LogMessage log = new LogMessage();
log.level = LogLevel.INFO;
log.date = System.currentTimeMillis();
log.msg = "SYSTEM: Configuration retrieved by client";
// log the configuration retrieval
log(cfg.id, log);
return cfg;
}
}
I am trying to write Junit Test cases for these controllers
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = { Application.class })
#WebAppConfiguration
public class ApiControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#Before
public void setup() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
#Test
public void getConfigurationSuccess() throws Exception {
mockMvc.perform(get("/agent/config").accept(MediaType.APPLICATION_JSON)).andExpect(status().is2xxSuccessful());
}
}
This is the stacktrace
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:980)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at backup.itests.ServiceTest.getConfigurationSuccess(ServiceTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
at backup.restservice.BaseRestController.getAgentConfigByIP(BaseRestController.java:25)
at backup.restservice.AgentRestController.getConfiguration(AgentRestController.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
... 39 more
Can Someone help me in writing JUnit or JBehave testcases for the the given two controller and Expanding the test case for the controllers in AgenRestController. This would be a Great and a constructive help.
private WebApplicationContext webApplicationContext;
#Before
public void setup() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
Just a shot in the dark here, but webApplicationContext is null, and not initialized. Perhaps before the this.mockMcx = ... you might insert the line:
webApplicationContext = new WebApplicationContext();