I'm building a JEE EAR application and I started working with EasyMock to create mocks for the repositories my services are using. But I am not quite sure the result is correct. Two tests in particular where I am testing void methods.
public class VenueServiceTest extends ServiceTest {
private VenueService venueService = new VenueServiceImpl();
private VenueRepository mockVenueRepository; // interface that the service is using
private List<Venue> venues;
private Venue venue1;
private Venue venue2;
#Override
public void setupMock() {
venues = MockUtils.getMockedVenues();
venue1 = venues.get(0);
venue2 = venues.get(1);
mockVenueRepository = createMock(VenueRepository.class);
venueService.setRepository(mockVenueRepository);
}
#Override
public void testUpdate() {
Venue originalVenue = new Venue(0L, "The Venue");
String originalName = originalVenue.getName();
mockVenueRepository.update(originalVenue);
expect(mockVenueRepository.findById(originalVenue.getId())).andReturn(originalVenue);
replay(mockVenueRepository);
originalVenue.setName("Another Venue");
venueService.updateEntity(originalVenue);
Venue newVenue = venueService.getEntity(originalVenue.getId());
String newName = newVenue.getName();
assertFalse("Venue names should not be equal", originalName.equals(newName));
verify(mockVenueRepository);
}
#Override
public void testDelete() {
expect(mockVenueRepository.findById(venue1.getId())).andReturn(venue1);
mockVenueRepository.remove(venue1);
expect(mockVenueRepository.findById(venue1.getId())).andReturn(null);
replay(mockVenueRepository);
assertNotNull(venueService.getEntity(venue1.getId()));
venueService.deleteEntity(venue1);
assertNull(venueService.getEntity(venue1.getId()));
verify(mockVenueRepository);
}
Both of these test passes. But if I comment out the delet/update parts they still pass.
#Override
public void testUpdate() {
Venue originalVenue = new Venue(0L, "The Venue");
String originalName = originalVenue.getName();
// mockVenueRepository.update(originalVenue);
expect(mockVenueRepository.findById(originalVenue.getId())).andReturn(originalVenue);
replay(mockVenueRepository);
originalVenue.setName("Another Venue");
// venueService.updateEntity(originalVenue);
Venue newVenue = venueService.getEntity(originalVenue.getId());
String newName = newVenue.getName();
assertFalse("Venue names should not be equal", originalName.equals(newName));
verify(mockVenueRepository);
}
#Override
public void testDelete() {
expect(mockVenueRepository.findById(venue1.getId())).andReturn(venue1);
// mockVenueRepository.remove(venue1);
expect(mockVenueRepository.findById(venue1.getId())).andReturn(null);
replay(mockVenueRepository);
assertNotNull(venueService.getEntity(venue1.getId()));
// venueService.deleteEntity(venue1);
assertNull(venueService.getEntity(venue1.getId()));
verify(mockVenueRepository);
}
Am I doing this right? My guess is no and if so how do you test this properly?
Thank you!
For the update, you are recording to return originalVenue. Since you are modifying its name, it will indeed be different. There is only one instance of originalVenue through all the test.
For delete, you are recording venue1 and then null. So if you call findById twice, you will receive venue1 and null. The test the delete, you can mock only the remove method to make sure it is called. Calling getEntity makes you test getEntity which is unrelated with the delete.
Basically, to test update and delete, I would do
#Override
public void testUpdate() {
Venue originalVenue = new Venue(0L, "The Venue");
String originalName = originalVenue.getName();
mockVenueRepository.update(originalVenue);
replay(mockVenueRepository);
originalVenue.setName("Another Venue");
venueService.updateEntity(originalVenue);
verify(mockVenueRepository);
}
#Override
public void testDelete() {
mockVenueRepository.remove(venue1);
replay(mockVenueRepository);
venueService.deleteEntity(venue1);
verify(mockVenueRepository);
}
Related
Please need to test this method paramsRequired but not as it can reproduce the behavior for testing. How to know if when passing the null parameters the method will skip the if?
My class service
public class TestStack {
private GeoClassService service;
public Address getAddress(String city,String neighborhood, boolean listOut) {
List<GeoLocation> listLocation = new ArrayList<>();
FutureTask<List<GeoLocation>> returnLoc = null;
Address location = new Address();
boolean paramsRequired = city!=null || neighborhood!=null;
if (listOut && paramsRequired) {
returnLoc = new FutureTask<>(() ->
service.getAdrres(city,neighborhood, listOut));
execute.executor(returnLoc);
}
return location;
}
}
my unit test
public class TestStackTests {
#InjectMocks
private TestStack stack;
#Test
public void paramsTest() {
Address paramsRequired = Mockito.spy(stack.getAddress(
"any city", "any", true));
boolean newAddres = paramsRequired==null;
Assert.assertFalse(newAddres);
}
}
I don't think I'm testing anything but honestly, I don't know how to do this test
I created a room database following this guide from code labs It makes use of a repository to:
A Repository manages query threads and allows you to use multiple backends. In the most common example, the Repository implements the logic for deciding whether to fetch data from a network or use results cached in a local database.
I followed the guide and i'm now able to create the entity's & retrieve the data. I even went further and created another whole entity outside the scope of the guide.
However I can't find many resources that use this MVVM(?) style so am struggling as to really under stand the repository. For now I want to update a field. Just one, as if I am able to manage that the rest should be similar.
I want to update a field called dartshit and I have the dao method created for this:
#Query("UPDATE AtcUserStats SET dartsHit = :amount WHERE userName = :userName")
void UpdateHitAmount(int amount, String userName);
I have one repository which I assumed I use for all entities:
public class UsersRepository {
private UsersDao mUsersDao;
private AtcDao mAtcDao;
private LiveData<List<Users>> mAllUsers;
private LiveData<List<AtcUserStats>> mAllAtc;
private AtcUserStats mAtcUser;
UsersRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mUsersDao = db.usersDao();
mAtcDao = db.atcDao();
mAllUsers = mUsersDao.fetchAllUsers();
mAllAtc = mAtcDao.getAllAtcStats();
}
LiveData<List<Users>> getAllUsers() {
return mAllUsers;
}
LiveData<List<AtcUserStats>> getAllAtcStats() {
return mAllAtc;
}
LiveData<AtcUserStats> getAtcUser(String username) {
return mAtcDao.findByName(username);
}
public void insert (Users user) {
new insertAsyncTask(mUsersDao).execute(user);
}
public void insertAtc (AtcUserStats atc) {
new insertAsyncAtcTask(mAtcDao).execute(atc);
}
private static class insertAsyncTask extends AsyncTask<Users, Void, Void> {
private UsersDao mAsyncTaskDao;
insertAsyncTask(UsersDao dao) {
mAsyncTaskDao = dao;
}
#Override
protected Void doInBackground(final Users... params) {
mAsyncTaskDao.insertNewUser(params[0]);
return null;
}
}
private static class insertAsyncAtcTask extends AsyncTask<AtcUserStats, Void, Void> {
private AtcDao mAsyncTaskDao;
insertAsyncAtcTask(AtcDao dao) {
mAsyncTaskDao = dao;
}
#Override
protected Void doInBackground(final AtcUserStats... params) {
mAsyncTaskDao.insertNewAtcUser(params[0]);
return null;
}
}
}
My question is how do I create a AsyncTask for the update query I am trying to run in this repository?
Here is what I have so far by broadly copying the insert repository methods:
private class updateHitAsyncTask {
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
protected Void doInBackground(int amount, String name) {
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
Which is incorrect is that I'm getting a llegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. error. But i thought this AsyncTask is suppose to take care of this?
Here is my update method in my view model, which is reporting 0 errors:
void updateHitAmount (int amount, String name) {
mRepository.updateAtcHits(amount, name);
}
and here is the UI code where im actually trying to tie all these together, I suspect there must be a better way that using onChanged for simply updating a field but again I am struggling to come across any advice on google with the repository approach:
private void callOnChanged() {
mAtcViewModel = ViewModelProviders.of(this).get(AtcViewModel.class);
mAtcViewModel.getAllUsers().observe(this, new Observer<List<AtcUserStats>>() {
#Override
public void onChanged(#Nullable final List<AtcUserStats> atc) {
// Update the cached copy of the users in the adapter.
for (int i = 0; i < atc.size(); i++) {
if (atc.get(i).getUserName().equals(mUser)) {
mAtcViewModel.updateHitAmount(55, mUser);
//atc.get(i).setDartsHit(55);
Log.d("id", String.valueOf(userSelected.getId()));
}
}
}
});
How can I update fields using this approach on the background thread?
Figured it out due to this answer here. It was mostly because of my lack of understanding of AsyncTask. Essentially I needed to create an object and pass the data that way and then execute in the background:
private static class MyTaskParams {
int amount;
String name;
MyTaskParams(int amount, String name) {
this.amount = amount;
this.name = name;
}
}
public void updateAtcHits (int amount, String name) {
MyTaskParams params = new MyTaskParams(amount,name);
new updateHitAsyncTask(mAtcDao).execute(params);
}
private class updateHitAsyncTask extends AsyncTask<MyTaskParams,Void,Void>{
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
#Override
protected Void doInBackground(MyTaskParams... myTaskParams) {
int amount =myTaskParams[0].amount;
String name = myTaskParams[0].name;
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
I have an interface:
public interface SenderService {
String send(long amount);
}
And I have an implementation of this interface:
public class SenderServiceAdapter implements SenderService {
private final ThirdPartyService thirdPartyService;
public SenderServiceAdapter(ThirdPartyService thirdPartyService) {
this.thirdPartyService = thirdPartyService;
}
#Override
public String send(long amount) {
ThirdPartyRequest thirdPartyRequest = new ThirdPartyRequest();
thirdPartyRequest.setAmount(amount);
thirdPartyRequest.setId(UUID.randomUUID().toString());
thirdPartyRequest.setDate(new Date());
ThirdPartyResponse thirdPartyResponse = thirdPartyService.send(thirdPartyRequest);
String status = thirdPartyResponse.getStatus();
if (status.equals("Error")) throw new RuntimeException("blablabla");
return thirdPartyResponse.getMessage();
}
}
Now I want to write Unit test for this service. I need to mock thirdPartyService's method send. But I don't understand how.
public class SenderServiceAdapterTest {
private ThirdPartyService thirdPartyService;
private SenderService senderService;
#Before
public void setUp() throws Exception {
thirdPartyService = Mockito.mock(ThirdPartyService.class);
senderService = new SenderServiceAdapter(thirdPartyService);
}
#Test
public void send() {
when(thirdPartyService.send(new ThirdPartyRequest())).thenReturn(new ThirdPartyResponse());
String message = senderService.send(100L);
}
}
The ThirdPartyRequest creates in SenderServiceAdapter. How can I mock it?
Try this:
doReturn(new ThirdPartyResponse()).when(thirdPartyService).send(any(ThirdPartyRequest.class));
Also by looking your code, you will need to set something in the response, so you will have to do this:
ThirdPartyResponse response = new ThirdPartyResponse(); //or mock
response.setStatus(...);
response.setMessage(...);
doReturn(response).when(thirdPartyService).send(any(ThirdPartyRequest.class));
I am currently doing a small project on spring-mvc in my backend and I am trying to create tests for my converters and engines. Below is my BookmarkEngine.java file
#Service
public class BookmarkEngine implements IBookmarkEngine{
private static final String URL_PREFIX = "http://";
#Override
public String getFullUrl(String url) {
if(!url.startsWith(URL_PREFIX))
{
return URL_PREFIX + url;
}
return url;
}
}
How would I go about writing a test for this?
Here is my BookmarkEngineTest:
public class BookmarkEngineTest {
IBookmarkEngine bookmarkEngine = new BookmarkEngine();
private ViewBookmark defaultBookmark;
#Before
public void setUp() throws Exception {
defaultBookmark = new ViewBookmark();
defaultBookmark.setBookmarkId(1L);
defaultBookmark.setTitle("A sample bookmark");
defaultBookmark.setUrl("This is a sample bookmark.");
defaultBookmark.setAuthor(".");
defaultBookmark.setLastUpdated(1497812309081L);
}
#Test
public void getFullUrl() {
String result = bookmarkEngine.getFullUrl(defaultBookmark.getUrl());
assertThat(result.length(), is(defaultBookmark.getUrl().length()));
}
}
That certain test in getFullUrl() does not run, but how can I can make it work?
You can make a test to see if the strings will match such as
#Test
public void getFullUrl() {
String testurl = "facebook.com";
String testurl2 = "http://facebook.com";
assertEquals(bookmarkEngine.getFullUrl(testurl),"http://facebook.com");
assertEquals(bookmarkEngine.getFullUrl(testurl2),"http://facebook.com");
}
I'm using Robospice with Retrofit ans ORMLite modules. Retrofit part working good. I have City model for Retrofit:
City.java:
public class City {
public int city_id;
public String name;
#SuppressWarnings("serial")
public static class List extends ArrayList<City> {
}
}
I'm taking this model from server by GET-request:
MyApi.java
public interface MyAPI {
#GET("/cities")
City.List getCities();
}
This part works fine by calling this method:
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
and listener:
public final class ListCityRequestListener implements RequestListener<City.List> {
#Override
public void onRequestFailure(SpiceException spiceException) {
Toast.makeText(RegisterActivity.this, "failure", Toast.LENGTH_SHORT).show();
}
#Override
public void onRequestSuccess(final City.List result) {
Toast.makeText(RegisterActivity.this, "success", Toast.LENGTH_SHORT).show();
updateCities(result);
}
}
At this time i want to download city list once from server and store this list into sqlitedb by ORMLite module. I've created ORMLite model:
City.java
#DatabaseTable(tableName = "city")
public class City {
public final static String DB_CITY_ID_FIELD_NAME = "id";
public final static String DB_CITY_NAME_FIELD_NAME = "name";
#DatabaseField(canBeNull = false, dataType = DataType.INTEGER, columnName = DB_CITY_ID_FIELD_NAME)
int id;
#DatabaseField(canBeNull = false, dataType = DataType.STRING, columnName = DB_CITY_NAME_FIELD_NAME)
private String name;
public City() {
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("id = ").append(id);
sb.append(", ").append("name = ").append(name);
return sb.toString();
}
}
My RetrofitSpiceService.java looks like this:
public class RetrofitSpiceService extends RetrofitGsonSpiceService {
private final static String BASE_URL = "http://example.com/api/v1";
private final static UserFunctions userFunctions = new UserFunctions();
#Override
public CacheManager createCacheManager(Application application) throws CacheCreationException {
CacheManager cacheManager = new CacheManager();
List< Class< ? >> classCollection = new ArrayList< Class< ? >>();
// add persisted classes to class collection
classCollection.add( City.class );
// init
RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper( application, "sample_database.db", 1 );
InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory( application, databaseHelper, classCollection );
cacheManager.addPersister( inDatabaseObjectPersisterFactory );
return cacheManager;
}
#Override
protected Builder createRestAdapterBuilder() {
Builder mBuilder = super.createRestAdapterBuilder();
mBuilder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
if (userFunctions.isUserLoggedIn()) {
request.addHeader("Authorization", userFunctions.getToken());
}
}
});
return mBuilder;
}
#Override
public void onCreate() {
super.onCreate();
addRetrofitInterface(MyAPI.class);
}
#Override
protected String getServerUrl() {
return BASE_URL;
}
}
I can't understand how can i store and read data from my City database? How do i need to change RetrofitSpiceService? I want download data by Retrofit and store it to database by ORMLite. My CacheManager is correct, i.e. will work properly? Maybe I misunderstand how the module Robospice-ORMLite works?
Thanks a lot!
When you make execute() call with cache key and duration Robospice will store your response into database.
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
All following requests during one minute will get data from this cache, and then it makes network call. If you want to get data only from cache take a look on getSpiceManager().getFromCache() method. I think it's what you are looking for.