Spring 4, Mockito 2, Junit 4 in Eclipse Oxygen - DAO not mocked - eclipse

I have an annotated Junit 4 test using JDK 1.8 running in Eclipse. I'm using Mockito to mock the DAO in the service class under test. The runner in the abstract class extends SpringJUnit4ClassRunner. When I run the test, the unimplemented method in the concrete DAO class is called, instead of the mocked method. I've searched and searched, and can't seem to find a solution. What am I doing wrong?
SOLVED - I changed the #InjectMocks #Autowired IOrganizationsService organizationsService; to remove the interface and autowiring, #InjectMocks OrganizationsService organizationsService; fixed below, and the DAO gets mocked. Now the question, why wasn't the DAO in the declaration using the interface mocked?
#ContextConfiguration(classes = { AppXmlConfigTest.class, AppConfig.class }, inheritLocations = false)
#WebAppConfiguration
public class MockOrganizationsServiceTest extends AbstractCoreJunit4Test {
public MockOrganizationsServiceTest() {
super();
}
#InjectMocks
OrganizationsService organizationsService;
#Mock
IOrganizationsDao organizationsDao;
#Before
public void setupMock() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testGetOrganizations() {
LocalDate localDate = LocalDate.now();
List<OrganizationTypeEnum> organizationTypes = new ArrayList<OrganizationTypeEnum>();
organizationTypes.add(OrganizationTypeEnum.All);
List<AllocationStatusEnum> allocationStatuses = new ArrayList<AllocationStatusEnum>();
allocationStatuses.add(AllocationStatusEnum.ALL);
List<IOrganization> organizations = new ArrayList<IOrganization>();
IOrganization organization = new Organization();
organization.setOrganizationId(1);
organizations.add(organization);
Mockito.when(organizationsDao.getOrganizations(isA(LocalDate.class), isA(List.class), isA(List.class))).thenReturn(organizations);
List<IOrganization> orgs = organizationsService.getOrganizations(localDate, organizationTypes, allocationStatuses);
assertNotNull(orgs);
}
}
The service class is this,
public class OrganizationsService extends AbstractService implements IOrganizationsService {
#Autowired
IOrganizationsDao organizationsDao;
/**
* #param organizationsDao the organizationsDao to set
*/
public void setOrganizationsDao(IOrganizationsDao organizationsDao) {
this.organizationsDao = organizationsDao;
}
#Override
public List<IOrganization> getOrganizations(LocalDate effectiveDate, List<OrganizationTypeEnum> organizationTypes, List<AllocationStatusEnum> allocationStatuses) {
return organizationsDao.getOrganizations(effectiveDate, organizationTypes, allocationStatuses);
}
and the DAO is this,
public class OrganizationsDao extends AbstractDao implements IOrganizationsDao {
#Override
public List<IOrganization> getPendingOrganizations(LocalDate effectiveDate) {
// TODO Auto-generated method stub
return null;
}
#Override
public List<IOrganization> getOrganizations(LocalDate effectiveDate, List<OrganizationTypeEnum> organizationTypeEnums,
List<AllocationStatusEnum> allocationStatuses) {
// TODO Auto-generated method stub
return null;
}

I think the issue here is that while mocking the method call you are using isA for parameters. As per my understanding, isA method is used for the verification not for passing the parameters. Try any method instead:
Mockito.when(organizationsDao.getOrganizations(any(LocalDate.class), any(List.class), any(List.class))).thenReturn(organizations);

Related

#Inject constructor with parameters

I saw a method of using #inject annotation with parameter constructor. I found no use in #module in all parts of the project. I don't understand how this code injects or provides parameters in the constructor.
Can you help me analyze it?
Where is the datamanager provided?
In the whole project, #module + #provide is not used to provide datamanager. I only know that #inject can only annotate the parameterless constructor. I don't know where to instantiate the parameterless datamanager object. Thank you for your help
application:
public class Scallop extends Application {
private ApplicationComponent applicationComponent;
#Override
public void onCreate() {
super.onCreate();
applicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.build();
}
public ApplicationComponent getApplicationComponent() {
return applicationComponent;
}
}
application module:
#Module
public class ApplicationModule {
private Scallop application;
public ApplicationModule(Scallop application) { // 提供类的构造器,传入Applicaton
this.application = application;
}
#Provides
#Singleton
Application provideApplication() {
return application;
}
#Provides
#ApplicationContext
Context provideContext() {
return application;
}
#Provides
#Singleton
Retrofit provideRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return retrofit;
}
#Provides
#Singleton
GankIOService provideGankIOService(Retrofit retrofit) {
return retrofit.create(GankIOService.class);
}
}
#Singleton
#Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
Application getApplication();
DataManager getDataManager();
}
```
one class:
#Singleton
public class DataManager {
private GankIOService gankIOService;
private PreferencesHelper preferencesHelper;
#Inject
public DataManager(GankIOService gankIOService, PreferencesHelper preferencesHelper) {
this.gankIOService = gankIOService;
this.preferencesHelper = preferencesHelper;
}
}
fragment module:
#FragmentScope
#Component(modules = FragmentModule.class, dependencies = ApplicationComponent.class)
public interface FragmentComponent {
void inject(HomeFragment homeFragment);
void inject(GanHuoPageFragment pageFragment);
void inject(XianDuFragment xianDuFragment);
void inject(XianDuPageFragment xianDuPageFragment);
void inject(PicturesFragment picturesFragment);
void inject(MoreFragment moreFragment);
}
#FragmentScope
#Documented
#Scope
#Retention(value = RetentionPolicy.RUNTIME)
public #interface FragmentScope {
}
```
here Can't understand constructor with parameter is #inject
public class GanHuoPagePresenter extends BasePresenter<GanHuoPageContract.View>
implements GanHuoPageContract.Presenter {
private DataManager dataManager;
private Disposable disposable;
#Inject
public GanHuoPagePresenter(DataManager dataManager) { // here here
this.dataManager = dataManager;
}
#Override
public void detachView() {
super.detachView();
if (disposable != null) {
disposable.dispose();
}
}
#Override
public void getGanHuo(String category, final int page) {
final List<GanHuo> ganHuoList = new ArrayList<>();
Observable<BaseResponse<GanHuo>> observable = dataManager.getGanHuo(category, page);
disposable = observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.concatMap(new Function<BaseResponse<GanHuo>, ObservableSource<GanHuo>>() {
#Override
public ObservableSource<GanHuo> apply(#NonNull BaseResponse<GanHuo> ganHuoBaseResponse)
throws Exception {
return Observable.fromIterable(ganHuoBaseResponse.getResults());
}
}).filter(new Predicate<GanHuo>() {
#Override
public boolean test(#NonNull GanHuo ganHuo) throws Exception {
return !ganHuo.getType().equals("福利");
}
}).subscribe(new Consumer<GanHuo>() {
#Override
public void accept(GanHuo ganHuo) throws Exception {
ganHuoList.add(ganHuo);
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
getView().showError(throwable.getMessage());
}
}, new Action() {
#Override`enter code here`
public void run() throws Exception {
getView().showList(ganHuoList, page);
}
});
}
}
This is how it is used in V in MVP mode:
#Inject GanHuoPagePresenter presenter
That's constructor injection. By marking a constructor with #Inject Dagger knows about the object and can create it when needed. There's no need for modules, e.g. the following is a valid Dagger setup to create some Foo.
public class Foo {
#Inject
public Foo() {}
}
#Component
interface MyComponent {
Foo getFoo();
}
That's not true that #Inject can only annotate the parameterless constructor. From documentation
Injectable constructors are annotated with #Inject and accept zero or more dependencies as arguments.
I found "your" project on Github so let's see where dependencies for GanHuoPagePresenter come from.
#Inject
public GanHuoPagePresenter(DataManager dataManager) {
this.dataManager = dataManager;
}
#Inject
public DataManager(GankIOService gankIOService,PreferencesHelper preferencesHelper){
// gankIOService is provided by ApplicationModule and preferencesHelper uses constructor injection
this.gankIOService = gankIOService;
this.preferencesHelper = preferencesHelper;
}
#Inject
public PreferencesHelper(#ApplicationContext Context context){
// context is provided again by ApplicationModule
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
}

Guice module integration issue with REST

Guice module integration issue with REST
I have define one AOP guice based module, but when I tried to integrate with REST code, methodInvocation.proceed retun null.
What might be best way to solve this issue.
Define AOP Guice based module as below
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
#interface NotOnWeekends {}
public class WeekendBlocker implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
Calendar today = new GregorianCalendar();
if (today.getDisplayName(DAY_OF_WEEK, LONG, ENGLISH).startsWith("S")) {
throw new IllegalStateException(
invocation.getMethod().getName() + " not allowed on weekends!");
}
return invocation.proceed();
}
}
public class NotOnWeekendsModule extends AbstractModule {
protected void configure() {
bindInterceptor(Matchers.any(), Matchers.annotatedWith(NotOnWeekends.class),
new WeekendBlocker());
}
}
But I tried to Integrate this with my REST API
public class WorkerBean implements Worker {
#Autowired
private WorkerRepository workerRepository;
#Override
#NotOnWeekends
public Collection<Worker> findAll() {
Collection<Worker> workers = workerRepository.findAll();
return workers;
}
#RestController
public class WorkerController {
#RequestMapping(
value = "/api/workers",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Worker>> getWorkers() {
Worker worker = Guice.createInjector(new NotOnWeekendsModule()).getInstance(Worker.class);
Collection<Worker> worker = worker.findAll(); // return null
....
}

How to inject Spring DAO class in QuartzJobBean, using JobDetailFactoryBean Annotated way

How to inject Spring DAO class in QuartzJobBean, I am using JobDetailFactoryBean instantiated at Config class level. I am using Spring4 Quartz 2.2.1 Annotation ways
#Configuration
public class SchedulerConfig {
#Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(SchedulerService.class);
//Should I inject DAO here?
factory.setGroup("mygroup");
factory.setName("myjob");
return factory;
}
}
QuartzJobBean been extended to execute
#PersistJobDataAfterExecution
#DisallowConcurrentExecution
#Service
public class SchedulerService extends QuartzJobBean {
#Autowire
public SchedulerDAO schDAO;
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
System.out.println("---SchedulerService .executeInternal ----");
try {
init(ctx.getJobDetail().getJobDataMap(),
ctx.getScheduler().getContext());
} catch (SchedulerException e) {
e.printStackTrace();
}
// I want to do DAO methods used here - how to do that?
// Can get access to DAO
schDAO.getSomeMethods();
}
}
Your problem is that Quartz, does not know anything about your configuration class, so it can't autowired an unknown bean.
Go to SchedulerConfig.java and declare your service or DAO as autowired, then use a jobdata and map this object in order to be passed in Quartz. Then you can use it inside executeInternal method of Quartz.
For example
#Configuration
public class mplampla{
#Autowired
private YourDAO dao;
#Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
Map<String,Object> map = new HashMap<String,Object>();
map.put("YourDAO", dao);
factory.setJobDataAsMap(map);
return factory;
}
}
Then in your YourJob.java
public class YourJob extends QuartzJobBean {
#Override
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
JobDataMap dataMap = ctx.getJobDetail().getJobDataMap();
YourDAO dao = (YourDAO) dataMap.get("YourDAO");
dao.getMethods();
}
}
Be carefull if you are using #Service class and YourDAO class as #Transational, you will get error about undeclared Bean. In this case you have to pass the inteface of your DAO.

Junit 4 + Eclipse - Run inner class test cases with SpringJUnit4ClassRunner as well

I need to run inner class test cases from eclipse using Junit4. I understand that there is org.junit.runners.Enclosed that is intended to serve this purpose. It works well for "plain" unit test i.e. without the need for spring context configuration.
For my case, give sample code below, Adding another annotation of Enclosed does not work since there is a conflict of both SpringJUnit4ClassRunner and Enclosed test runners. How can I solve this problem ?
Note: Kindly ignore any basic spelling mistake/basic import issues in the below example since I tried to cook up from my actual use-case.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/unit-test-context.xml"})
public class FooUnitTest {
// Mocked dependency through spring context
#Inject
protected DependentService dependentService;
public static class FooBasicScenarios extends FooUnitTest{
#Test
public void testCase1 {
.....
List<Data> data = dependentService.getData();
.....
}
}
public static class FooNeagativeScenarios extends FooUnitTest{
#Test
public void testCase1 {
.....
List<Data> data = dependentService.getData();
.....
}
}
}
}
FooUnitTest is a container, you cannot use it as a superclass.
You need to move all your spring-code to Scenario-classes. And use #RunWith(Enclosed.class). For example, with abstract superclass
#RunWith(Enclosed.class)
public class FooUnitTest {
#ContextConfiguration(locations = { "/unit-test-context.xml"})
protected abstract static class BasicTestSuit {
// Mocked dependency through spring context
#Inject
protected DependentService dependentService;
}
#RunWith(SpringJUnit4ClassRunner.class)
public static class FooBasicScenarios extends BasicTestSuit {
#Test
public void testCase1 {
.....
List<Data> data = dependentService.getData();
.....
}
}
#RunWith(SpringJUnit4ClassRunner.class)
public static class FooNeagativeScenarios extends BasicTestSuit {
#Test
public void testCase1 {
.....
List<Data> data = dependentService.getData();
.....
}
}
}
Of course you can declare all dependencies in each Scenario-class, in that case there is no necessary in abstract superclass.

How to use provider in Errai IOC?

I have a problem with #IocProvider (), annotation does not work.
The code is very similar to https://docs.jboss.org/author/display/ERRAI/Container+Wiring
public interface Test {
String getGreeting();
}
#ApplicationScoped
public class TestImpl implements Test {
public String getGreeting() {
return "Hello:)";
}
}
#IOCProvider
#Singleton
public class TestProvider implements Provider<Test> {
#Override
public Test get() {
return new TestImpl();
}
}
Then I want use DI in my broadcast service (errai-bus).
#Service
public class BroadcastService implements MessageCallback {
#Inject
Test test;
#Inject
MessageBus bus;
#Inject
public BroadcastService(MessageBus bus) {
this.bus = bus;
}
public void callback(Message message) {
MessageBuilder.createMessage()
.toSubject("BroadcastReceiver")
.with("BroadcastText", test.getGreeting()).errorsHandledBy(new ErrorCallback() {
#Override
public boolean error(Message message, Throwable throwable) {
return true;
}
}).sendNowWith(bus);
}
}
I get a error:
1) No implementation for com.gwtplatform.samples.basic.server.Test was bound.
while locating com.gwtplatform.samples.basic.server.Test
for field at com.gwtplatform.samples.basic.server.BroadcastService.test(BroadcastService.java:32)
at org.jboss.errai.bus.server.service.ServiceProcessor$1.configure(ServiceProcessor.java:118)
If I change the code to
#Inject
TestImpl test;
It works, but I need the provider. Do you have some idea?
Because you're trying to use #IOCProvider in server-side code. Errai IOC is completely client-side.