Junit with new Date() - date

What would the junit test be when i have the following method:
#Override
public void saveLastSuccesfullLogin(final User user) {
gebruiker.setLastLogin(new Date());
storeUser(user);
}
submethode storeUser:
#Override
public void storeUser(final User user) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.merge(user);
em.getTransaction().commit();
em.close();
}
The problem i have is the date, being set for the entity user and then stored. Im using junit and easymock.

Try pulling the new Date() into a method with default access specifier like below
#Override
public void saveLastSuccesfullLogin(final User user) {
gebruiker.setLastLogin(getDate());
storeUser(user);
}
Date getDate() {
return new Date();
}
In your test class override the class as below using a mock or stubbed date.
<ClassUnderTest> classUnderTest = new <ClassUnderTest> () {
#Override
Date getDate() {
return mockDate;
}
}
In this way you can assert the date value easily as it is going to be stubbed out.

What's the problem with the Date? That you don't know what it is to assert later? A few alternatives:
Pass the date into the method
Create a factory to get the current date/time so you can mock it out
Assert the date within a threshold of correctness

There is also a more "enterprise" approach that may be used where Dependency Injection is available (like in EJB, Spring etc.).
You can define an interface, for example TimeService and add e method that returns the current date.
public interface TimeService {
Date getCurrentDate();
}
You can implement this to return new Date() and use it like this:
gebruiker.setLastLogin(timeService.getCurrentTime());
This will obviously be very easy to test because you can mock the TimeService. Using EasyMock (just an example), this might be:
Date relevantDateForTest = ...
expect(timeService.getCurrentTime()).andReturn(relevantDateForTest);
replay(timeService);
Using the TimeService throughout the entire code and never using new Date() is a pretty good practice and has other advantages as well. I found it helpful in a number of occasions, including manual functional testing of features that would activate in the future. Going even further, the system time may be retrieved from an external system thus making it consistent across clusters etc.

You can also create a getDate method, and a date static var:
private static Date thisDate = null;
#Override
public void saveLastSuccesfullLogin(final User user) {
gebruiker.setLastLogin(getDate());
storeUser(user);
}
public Date getDate() {
if(thisDate != null) return thisDate;
return new Date();
}
public void setDate(Date newDate) {
thisDate = newDate;
}
Then in your test method, you can go ahead and call setDate to control what date you will get.

Related

JPA : Update operation without JPA query or entitymanager

I am learning JPA, I found out that we have some functions which is already present in Jparepository like save,saveAll,find, findAll etc. but there is nothing like update,
I come across one scenario where I need to update the table, if the value is already present otherwise I need to insert the record in table.
I created
#Repository
public interface ProductInfoRepository
extends JpaRepository<ProductInfoTable, String>
{
Optional<ProductInfoTable> findByProductName(String productname);
}
public class ProductServiceImpl
implements ProductService
{
#Autowired
private ProductInfoRepository productRepository;
#Override
public ResponseMessage saveProductDetail(ProductInfo productInfo)
{
Optional<ProductInfoTable> productInfoinTable =
productRepository.findByProductName(productInfo.getProductName());
ProductInfoTable productInfoDetail;
Integer quantity = productInfo.getQuantity();
if (productInfoinTable.isPresent())
{
quantity += productInfoinTable.get().getQuantity();
}
productInfoDetail =
new ProductInfoTable(productInfo.getProductName(), quantity + productInfo.getQuantity(),
productInfo.getImage());
productRepository.save(productInfoDetail);
return new ResponseMessage("product saved successfully");
}
}
as you can see, I can save the record if the record is new, but when I am trying to save the record which is already present in table it is giving me error related to primarykeyviolation which is obvious. I checked somewhat, we can do the update by creating the entitymanager object or jpa query but what if I dont want to use both of them. is there any other way we can do so ?
update I also added the instance of EntityManager and trying to merge the code
#Override
public ResponseMessage saveProductDetail(ProductInfo productInfo)
{
Optional<ProductInfoTable> productInfoinTable =
productRepository.findByProductName(productInfo.getProductName());
ProductInfoTable productInfoDetail;
Integer price = productInfo.getPrice();
if (productInfoinTable.isPresent())
{
price = productInfoinTable.get().getPrice();
}
productInfoDetail =
new ProductInfoTable(productInfo.getProductName(), price, productInfo.getImage());
em.merge(productInfoDetail);
return new ResponseMessage("product saved successfully");
but no error, no execution of update statements in log, any possible reasons for that ?
}
I suspect you need code like this to solve the problem
public ResponseMessage saveProductDetail(ProductInfo productInfo)
{
Optional<ProductInfoTable> productInfoinTable =
productRepository.findByProductName(productInfo.getProductName());
final ProductInfoTable productInfoDetail;
if (productInfoinTable.isPresent()) {
// to edit
productInfoDetail = productInfoinTable.get();
Integer quantity = productInfoDetail.getQuantity() + productInfo.getQuantity();
productInfoDetail.setQuantity(quantity);
} else {
// to create new
productInfoDetail = new ProductInfoTable(productInfo.getProductName(),
productInfo.getQuantity(), productInfo.getImage());
}
productRepository.save(productInfoDetail);
return new ResponseMessage("product saved successfully");
}

Implementing pagination and sorting on a ReactiveMongoRepository with a dynamic query

I know pagination is somewhat against reactive principles, but due to requirements I have to make it work somehow. I'm using Spring Data 2.1.6 and I can't upgrade so ReactiveQuerydslSpecification for the dynamic query is out of the question. I figured I could use ReactiveMongoTemplate so I came up with this:
public interface IPersonRepository extends ReactiveMongoRepository<Person, String>, IPersonFilterRepository {
Flux<Person> findAllByCarId(String carId);
}
public interface IPersonFilterRepository {
Flux<Person> findAllByCarIdAndCreatedDateBetween(String carId, PersonStatus status,
OffsetDateTime from, OffsetDateTime to,
Pageable pageable);
}
#Repository
public class PersonFilterRepository implements IPersonFilterRepository {
#Autowired
private ReactiveMongoTemplate reactiveMongoTemplate;
#Override
public Flux<Person> findAllByCarIdAndCreatedDateBetween(String carId, PersonStatus status,
OffsetDateTime from, OffsetDateTime to,
Pageable pageable) {
Query query = new Query(Criteria.where("carId").is(carId));
if (status != null) {
query.addCriteria(Criteria.where("status").is(status));
}
OffsetDateTime maxLimit = OffsetDateTime.now(ZoneOffset.UTC).minusMonths(3).withDayOfMonth(1); // beginning of month
if (from == null || from.isBefore(maxLimit)) {
from = maxLimit;
}
query.addCriteria(Criteria.where("createdDateTime").gte(from));
if (to == null) {
to = OffsetDateTime.now(ZoneOffset.UTC);
}
query.addCriteria(Criteria.where("createdDateTime").lte(to));
// problem is trying to come up with a decent page-ish behavior compatible with Flux
/*return reactiveMongoTemplate.count(query, Person.class)
.flatMap(count -> reactiveMongoTemplate.find(query, Person.class)
.flatMap(p -> new PageImpl<Person>(p, pageable, count))
.collectList()
.map());*/
/* return reactiveMongoTemplate.find(query, Person.class)
.buffer(pageable.getPageSize(), pageable.getPageNumber() + 1)
//.elementAt(pageable.getPageNumber(), new ArrayList<>())
.thenMany(Flux::from);*/
}
I've tried to return a Page<Person> (assuming for once this single method could be non-reactive, for once) and it fails with the following error while running testing (Spring context does not load successfully due to: InvalidDataAccessApiUsageException: 'IDocumentFilterRepository.findAllByCustomerIdAndCreatedDateBetween' must not use sliced or paged execution. Please use Flux.buffer(size, skip). I've also tried returning Mono<Page<Person>> and then fails with "Method has to use a either multi-item reactive wrapper return type or a wrapped Page/Slice type. Offending method: 'IDocumentFilterRepository.findAllByCustomerIdAndCreatedDateBetween', so I guess my only option is returning a Flux, according to Example 133, snippet 3
Turns out you can just add the following to the query object:
query.with(pageable);
reactiveMongoTemplate.find(query, Person.class);
Return Flux<T> and it will work out of the box.

Custom OrderByComparator day of DateTime

I need to order my DynamicQuery by the number of day on a DateTimeColumn (Contact_ table by the way)
the default orderByComparator bring:
1969/04/02
1970/04/01
1970/04/01
1970/04/11
but I need
1970/04/01
1970/04/01
1969/04/02
1970/04/11
I tried overriding OrderByComparator and then using him on my dynamicQuery() method, but doesn't work
Tried to implement OrderByComparatorFactory myself but my compare method isn't called
I thing I can use a custom query, but there's no other way to do it?
by the way, I'am using a search container
DynamicQuery does not use compare method from an OrderByComparator method. DynamicQuery adds only the fields and asc/desc from the OrderByComparator.
See the Liferay code here:
BasePersistentImpl:
public List findWithDynamicQuery(
DynamicQuery dynamicQuery, int start, int end,
OrderByComparator orderByComparator)
throws SystemException {
OrderFactoryUtil.addOrderByComparator(dynamicQuery, orderByComparator);
return findWithDynamicQuery(dynamicQuery, start, end);
}
OrderFactoryUtil:
public static void addOrderByComparator(
DynamicQuery dynamicQuery, OrderByComparator obc) {
if (obc == null) {
return;
}
String[] orderByFields = obc.getOrderByFields();
for (String orderByField : orderByFields) {
if (obc.isAscending(orderByField)) {
dynamicQuery.addOrder(asc(orderByField));
}
else {
dynamicQuery.addOrder(desc(orderByField));
}
}
}
You may sort the result list by your comparator, as I did it in this example:
github

RxJava (or Rx.NET) equivalent of ReactiveCocoa's RACObserve

Given an arbitrary field on a Java object, I want to create an Observable that will watch that field and push a new result to an Observer every time the value of the field changes. ReactiveCocoa has a macro called RACObserve, which appears to do exactly this.
I want to know how to implement similar functionality using RxJava.
For example, say I had the following simple class:
public class Foo {
enum State {
Idle,
Ready,
Error
}
private State currentState = State.Idle;
//methods that can change currentState
}
I want to create an Observable<State> that will push the new state to an Observer every time something changes the value of currentState.
In ReactiveCocoa, it looks like I would write something sort of like the following (please excuse my pseudo Objective-C):
[RACObserve(self, currentState) subscribeNext:^(NSString *newState) {
NSLog(#"%#", newState);
}];
How would I achieve similar functionality in RxJava? I'm thinking that I may need to wrap all changes to currentState in a setter, but it's not clear to me where I should then call Observable.create and how to feed the changes of currentState to an Observer.
ReactiveCocoa is actually more similar to ReactiveUI (http://www.reactiveui.net) than just plain Rx. And in ReactiveUI, you can use this.WhenAnyValue(x => x.PropName) to do exactly what you want.
I stumbled across this same problem recently, I ended up using PropertyChangeListener, which will emit an object when a property is changed, see the following:
Update Listener:
public class GameUpdateListener {
public static Observable<Object> changed(Game game) {
final BehaviorSubject<Object> subject = BehaviorSubject.create((Object)game);
game.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
subject.onNext( (Object)propertyChangeEvent.getNewValue());
}
});
return subject;
}
}
Some custom object:
public class Game {
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
...
public setSomeField(String field){
this.field = field;
pcs.firePropertyChange("field", this.field, field);
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
pcs.addPropertyChangeListener(propertyChangeListener);
}
...
}
Observe:
Game game = new Game();
GameUpdateListener listener = new GameUpdateListener();
final Observable<Object> gameObserver = listener.changed(game);
gameObserver.subscribe(new Action1<Object>() {
#Override
public void call(Object o) {
Log.e(TAG, "Object Changed");
}
});
game.setSomeField("New value");
This will work fine as long as you don't need to instantiate your object again. Perhaps a solution to this is to create a local setter method and emit a change there.
Since your question title contains "or Rx.NET", here is my suggestion (I dunno bout RxJava, you may find something similar).
You probably will have to leverage some sort of mechanism in the setter. The standard way in .NET is by using the INotifyPropertyChanged interface.
Then by firing the events, you can create an IObservable<T> from this stream by using
Observable.FromEvent<TEvent, TArgs>()
You can find a really good example of what you want to do (.NET) here.
(credits to Rob Foncesa-Ensor)
I think what you are after is a Subject<T>. It implements IObserver<T>, so you can call OnNext(T) to fire a new value, as well as IObservable<T>, which you can expose it as publicly so it can be subscribed to.
If you need it to fire the latest value to new subscribers, you can use a ReplaySubject<T> with a buffer size of 1.
Here's a basic implementation:
public class SomeService
{
private Subject<int> values = new Subject<int>();
public IObservable<T> Values
{
get
{
// AsObservable prevents it from being cast back to Subject
return values.AsObservable();
}
}
// Private; called by some internal mechanism
private void SetValue(int newValue)
{
newValue.OnNext(newValue);
}
}

Asynchronous method in seam always return null QuartzTriggerHandle ?

QuartzTriggerHandle object that returned by Asynchronous method in Seam always 'null',
the job starts but cann't cancelled or paused.
In, seam forum i found the next example that should be work,but it doesn't work with me.
#Name("quartzObserver")
public class SCSQuartzObserver {
#In(create = true)
SCSQuartzTask quartzTask;
#SuppressWarnings("unused")
#Observer("org.jboss.seam.postInitialization")
public void observe() {
try {
Calendar cal = Calendar.getInstance();
cal.set(2040, Calendar.MAY, 10);
QuartzTriggerHandle handle = quartzTask.performTask(new Date(),
86400000l);
handle.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Name("quartzTask")
#AutoCreate
public class SCSQuartzTask {
#Asynchronous
public QuartzTriggerHandle performTask(#Expiration java.util.Date when,
#IntervalDuration long duration) {
// do stuff
QuartzTriggerHandle handle = new QuartzTriggerHandle("SCSQuartzTask");
return handle;
}
}
thnx for help.
You shouldn't create the QuartzTriggerHandle. Just do your work in the body of the performTask method, seam runtime will take care to return the QuartzTriggerHandle object. Something like this:
#Asynchronous
public QuartzTriggerHandle performTask(#Expiration java.util.Date when,
#IntervalDuration long duration) {
// do stuff
return null;
}
The QuartzTriggerHandle is serializable, you can keep it in a database table so you can later cancel the task.
Hi You must add something in component.xml
1-)async:quartz-dispatcher
2-)xsi:schemaLocation
http://jboss.com/products/seam/async
http://jboss.com/products/seam/async-2.2.xsd"
now it will work
you can find example Melih sakarya web site
http://www.melihsakarya.com/2011/09/seam-de-zamanli-isler-scheduling/