I use maven for managing dependencies in my project.
I have seen while writing test cases that some of them pass in eclipse while fail on maven build. I debugged it and found that there are static final members of classes being initialized once retain their values throughout the build. It is a multi-module project.
Is it possible to change the value of those final members for different test cases?
Please ask me if you want more clarification.
Any links/hints or ideas may be helpful.
Thanks.
The static final members are the Java way of expressing constants. First try to modify your test in such a way that it works with the values of these constants. If this is not possible, you can add a second constructor for testing purpose that overrides these values. See the following example:
Existing code:
public class SomeClass {
private static final int LIMIT = 30;
public SomeClass() {
...
}
public void doSomething() {
... //the code that uses LIMIT.
}
}
Add a second constructor that is used by the test:
public class SomeClass {
private static final int DEFAULT_LIMIT = 30;
private final limit
public SomeClass() {
this(DEFAULT_LIMIT);
}
public SomeClass(int limit) {
this.limit = limit;
...
}
public void doSomething() {
... //the code uses limit now.
}
}
Related
I am facing an weird PowerMock issue. Let me explain more in details.
My code:
#Service
public class TestMe {
#Autowired
private ClassA a;
#Autowired
private ClassB b;
#Autowired
private ClassStatic staticClass;
public void init(){
List<String> nameList = returnNames(); // Line#1
// Work with names
List<String> placeList = returnPlaces(); // Line#2
// Work with places
}
public List<String> returnNames(){
// Code to return list of names
}
public List<String> returnPlaces(){
// Code to return list of places
}
}
My Test Class
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClassStatic.class})
public class TestMeTest {
#Mock
private ClassA aMock;
#Mock
private ClassB bMock;
#InjectMocks
private TestMe testMeMock;
#Test
public void testInit(){
List<String> listNames = ... // some list of names
List<String> listPlaces = ... // some list of places
when(testMeMock.returnNames()).thenReturn(listNames);
// listPlaces gets returned in Line#1 shown in the main code.
when(testMeMock.returnPlaces()).thenReturn(listPlaces);
testMeMock.init();
}
}
So, as you see in line#1 I get listPlaces instead of listNames. If I rearrange the when calls then I get listNames instead of listPlaces at Line#2.
Why PowerMock confuses with the methods? Or there is something else I am missing while working with PowerMock.
I could solve the issue by using thenReturn twice like below
when(testMeMock.returnNames()).thenReturn(listNames).thenReturn(listPlaces);
// Removed the returnPlaces() call
// when(testMeMock.returnPlaces()).thenReturn(listPlaces);
testMeMock.init();
But why can't PowerMock distinguish between two different method calls returnNames() and returnPlaces()??
A different perspective. This here:
#InjectMocks
private TestMe testMeMock;
and that:
when(testMeMock.returnPlaces()).thenReturn(listPlaces);
simply doesn't make sense together.
The #InjectMocks annotation is meant to create an instance of your class under test, which gets "filled" with the other mocks you created via the #Mock annotation. But then you use that class under test instance like it were a mock (by going when(testMeMock.foo())).
You should start by stepping back and clarifying for yourself what exactly you intend to do. Probably partial mocking, because you want to test your init() method, but you also intend to control what other methods on your class under test do.
Finally, you might also want to step back and re-think your overall design. To have public methods returning lists, that are also used on a public method that does the init, that simply sounds wrong, too.
I am creating a program for testing a website. Site has a registration process, which I am testing.
I have created a class named "Client", which should store the information about the client (name, family name, e-mail etc.).
Since I am testing, I use random number generator to generate a name for the client (I have the list of names, one of which is chosen randomly).
Obviously, I should create a method "generateName ()".
But the question is: in which class I should create it?
Lots of programmers would create the method in the Client class. And would do something like that:
client = new Client ();
client.generateName ();
But I have read, that this approach is incorrect - because the client does not generate name for himself. Program does.
Based on that information, I do as follows:
class Program
{
private void generateName ();
}
...
class Client
{
...
public void name ( String name )
{
this.name = name;
}
}
program = new Program ();
program.launch();
client = new Client ();
client.name ( program.generateName () );
But as I know, this approach is not used by the developers.
Could you clarify, how to know "what is right and what is wrong" here? And what information source should I use as an arbitrary for the cases of this kind?
It sounds like generateName() could be a static method in Client, since it's independent of instances:
class Client {
private String name;
public Client(String name) {
this.name = name;
}
public static String generateRandomName() {
String generatedName = ...;
return generatedName;
}
}
You could the simply pass it's value to the Client object as you currently are, or via the constructor:
client = new Client(Client.generateRandomName());
Otherwise, I'd suggest a ClientNameGenerator to handle name generation, to keep inline with SRP and to raise cohesion. This would be the better choice, seeing how you may be needing more name generation methods in the future:
class ClientNameGenerator {
public String generateRandomName() {
String generatedName = ...;
return generatedName;
}
//other name generation methods...
}
You can now use a ClientNameGenerator object to manage the generation of client names:
ClientNameGenerator nameGenerator = new ClientNameGenerator();
client = new Client(nameGenerator.generateRandomName());
Anytime you need to generate a name, simply use the ClientNameGenerator object you created.
There are a number of places which might be appropriate locations for this functionality.
You could have it as a private method on the Client class, used by a static factory method for generating Clients with a random name.
public class Client {
....
public static Client randomlyNamed() {
return new Client(randomName());
}
private static String randomName() {
return ...;
}
}
But that private method might be better extracted to a more appropriate class for generating random Strings...
public class Client {
private static final int defaultNameLength = 8;
....
public static Client randomlyNamed() {
return new Client(Strings.randomString(defaultNameLength));
}
}
public class Strings
private static String randomString(int length) {
return ...;
}
}
You could then expand the static method into a general purpose ClientBuilder class, with an instance method named something like 'withRandomName()'.
public class Client {
...
}
public class ClientBuilder {
private static final int defaultNameLength = 8;
...
public ClientBuilder randomlyNamed() {
this.name = Strings.randomString(defaultNameLength);
}
public Client build() {
return new Client(name);
}
}
public class Strings
private static String randomString(int length) {
return ...;
}
}
An alternative would be an implementation of a NamingStrategy (e.g. ``) object which is given to a ClientBuilder object.
public class RandomNames implements NamingStrategy {
private static final int defaultNameLength = 8;
public String name() {
return String.randomString(defaultNameLength);
}
}
public class ClientBuilder {
private final NamingStrategy nameSource;
public ClientBuilder(NamingStrategy nameSource) {
this.nameSource = nameSource;
}
public Client build() {
return new Client(nameSource.name());
}
}
The pure way to go would be to have a separate class ClientGenerator that produces clients. Because generating clients is not typical client behavior and in your application model a client is no more than a passive data container for client properties. However, generating clients is an activity in "the client domain". Therefor it would be defendable to create a static method Client.NewClient(), like the .NET feamework does with Guid. On the other hand, a guid's very nature is to be generated, it does not represent something in the real world. It IS a spawnable id. So the comparison may not be all that ligitimate.
A common similar mistake (or impurity if you wish) is a Save method on an object. Instead one should have a Persister class that does the job. Or a Manager. Because Save is something you can do to or with the class, not behavior of the class ifself.
I thought I knew GWT serialization rules, but apparently I don't. This case is just weird, I'm trying to figure it out for couple of hours, still no luck. Maybe you, guys, could lend me a hand on this one?
First things first: the stack trace.
...blah blah blah...
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'geos.dto.common.client.Market' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = null
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
at com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase.serialize(Collection_CustomFieldSerializerBase.java:44)
at com.google.gwt.user.client.rpc.core.java.util.HashSet_CustomFieldSerializer.serialize(HashSet_CustomFieldSerializer.java:39)
at com.google.gwt.user.client.rpc.core.java.util.HashSet_CustomFieldSerializer.serializeInstance(HashSet_CustomFieldSerializer.java:51)
at com.google.gwt.user.client.rpc.core.java.util.HashSet_CustomFieldSerializer.serializeInstance(HashSet_CustomFieldSerializer.java:28)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeImpl(ServerSerializationStreamWriter.java:740)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:621)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
at com.extjs.gxt.ui.client.data.RpcMap_CustomFieldSerializer.serialize(RpcMap_CustomFieldSerializer.java:35)
... 78 more
So it appears the problem lies in geos.dto.common.client.Market. Let's see the minimal that still can be compiled.
package geos.dto.common.client;
public class Market extends RowModel<Integer> {
public static final String ID="id";
public static final String NAME="name";
public Market() { }
public Market(int id, String name) { }
public String getName() { }
public void setName(String name) { }
}
Either I really need a vacation, or it's just fine. A LOT of DTO classes inherit from RowModel, they are working and are serialized properly, no problems there. But of course I'll show you anyway. This time some GXT stuff ahead. This class is unedited, but still fairly simple.
package geos.dto.common.client;
import com.extjs.gxt.ui.client.data.BaseModelData;
public class RowModel<I> extends BaseModelData implements IdentifiableModelData<I> {
private I identifier;
private String identifierProperty;
public RowModel() { }
public RowModel(String identifierProperty) {
this.identifierProperty=identifierProperty;
}
#Override
public I getIdentifier() {
return identifier;
}
public void setIdentifier(I identifier) {
this.identifier = identifier;
if((identifierProperty!=null)&&(!identifierProperty.isEmpty())) {
set(identifierProperty,identifier);
}
}
public void setIdentifierProperty(String identifierProperty) {
this.identifierProperty = identifierProperty;
if(identifier!=null) {
set(identifierProperty,identifier);
}
}
public String getIdentifierProperty() {
return identifierProperty;
}
#Override
public <X> X set(String property, X value) {
if(property.equals(identifierProperty)&&((identifier==null)||(!getIdentifier().equals(value)))) {
setIdentifier((I)value);
}
return super.set(property, value);
}
}
Looks somewhat weird, I know, but these identifier is really important. I removed toString() which - in this case - returns null (because internal RpcMap is null, and it's null because no values are set in Market class). And the last piece of code, the interface implemented by RowModel:
package geos.dto.common.client;
import com.extjs.gxt.ui.client.data.ModelData;
import java.io.Serializable;
public interface IdentifiableModelData<I> extends ModelData, Serializable {
public I getIdentifier();
}
The versions are GWT 2.4.0 and GXT 2.2.5. I want to upgrade it soon, but first I want to deal with problems like this one.
And that would be all, I think. Do you see anything I can't see? I certainly hope so! Thanks!
Expecting, that your package structure follows the naming conventions: Is it possible that you have to move your Market-class into the shared package?
If you make a rcp call, the class is serialized on the client side and deserialized on the server side. There fore the class have to be accessible from the client and the server. If you class lies in the client-package, the server can't access this class. Classes that are used on the client and server side are put in a package called shared.
So, all classes that are only needed in your client, should be inside a package called client. Classes, that are needed on the server and the client side should be inside the shared package and classes, that are only neede on the server side are inside the server package.
This is my abstract class, that extends BaseModelData and lies inside the shared package:
package de.gishmo.leela.application.shared.models;
import java.io.Serializable;
import com.extjs.gxt.ui.client.data.BaseModelData;
#SuppressWarnings("serial")
public abstract class MyBaseModel
extends BaseModelData
implements Serializable {
public final static String MYFIELD = "myField";
public abstract String getModelName();
}
works well in RCP-calls.
And please implement the Serializable Interface.
I've got an oblivion.
The problem wasn't in that class, not at all. Thing is, it's transferred using another class, that extends RowModel as well. And it's set this way:
public void setMarkets(Set<Market> markets) {
set(MARKETS,markets);
}
And because I haven't included the Market type in that class, GWT didn't know it should be serialized at compilation time. Adding private Market _market; in that class did the trick. Actually it's well known issue related to subclasses of BaseModelData (that it can't serialize types that are not declared as class fields), but I totally forgotten it...
I want to run the same JUnit tests for different interface implementations. I found a nice solution with the #Parameter option:
public class InterfaceTest{
MyInterface interface;
public InterfaceTest(MyInterface interface) {
this.interface = interface;
}
#Parameters
public static Collection<Object[]> getParameters()
{
return Arrays.asList(new Object[][] {
{ new GoodInterfaceImpl() },
{ new AnotherInterfaceImpl() }
});
}
}
This test would be run twice, first with the GoodInterfaceImpl then with the AnotherInterfaceImpl class. But the problem is I need for most of the testcases a new object. A simplified example:
#Test
public void isEmptyTest(){
assertTrue(interface.isEmpty());
}
#Test
public void insertTest(){
interface.insert(new Object());
assertFalse(interface.isEmpty());
}
If the isEmptyTest is run after the insertTest it fails.
Is there an option to run automatically each testcase with a new instance of an implementation?
BTW: Implementing a clear() or reset()-method for the interface is not really an options since I would not need it in productive code.
Here is another approach with the Template Method pattern:
The interface-oriented tests go into the base class:
public abstract class MyInterfaceTest {
private MyInterface myInterface;
protected abstract MyInterface makeContractSubject();
#Before
public void setUp() {
myInterface = makeContractSubject();
}
#Test
public void isEmptyTest(){
assertTrue(myInterface.isEmpty());
}
#Test
public void insertTest(){
myInterface.insert(new Object());
assertFalse(myInterface.isEmpty());
}
}
For each concrete class, define a concrete test class:
public class GoodInterfaceImplTest extends MyInterfaceTest {
#Override
protected MyInterface makeContractSubject() {
// initialize new GoodInterfaceImpl
// insert proper stubs
return ...;
}
#Test
public void additionalImplementationSpecificStuff() {
...
}
}
A slight advantage over #Parameter is that you get the name of the concrete test class reported when a test fails, so you know right away which implementation failed.
Btw, in order for this approach to work at all, the interface must be designed in a way which allows testing by the interface methods only. This implies state-based testing -- you cannot verify mocks in the base test class. If you need to verify mocks in implementation-specific tests, these tests must go into the concrete test classes.
Create a factory interface and implementations, possibly only in your test hierarchy if you don't need such a thing in production, and make getParameters() return a list of factories.
Then you can invoke the factory in a #Before annotated method to get a new instance of your actual class under test for each test method run.
Just in case somebody reaches here(like I did), looking for testing multiple implementations of the same interface in .net you could see one of the approaches that I was using in one of the projects here
Below is what we are following in short
The same test project dll is run twice using vstest.console, by setting an environment variable. Inside the test, (either in the assembly initialize or test initialize) register the appropriate implementations into a IoC container, based on the environment variable value.
In Junit 5 you could do:
#ParameterizedTest
#MethodSource("myInterfaceProvider")
void test(MyInterface myInterface) {}
static Stream<MyInterface> myInterfaceProvider() {
return Stream.of(new ImplA(), new ImplB());
}
interface MyInterface {}
static class ImplA implements MyInterface {}
static class ImplB implements MyInterface {}
In my application I'm getting some data from a file located in the server. The data is stored in a text file (.obj), so I'm using an rpc to read the file and get the data. The file is read using a third party library http://www.pixelnerve.com/processing/libraries/objimport/ I'm sending the data to the client using ArrayLists, basicly I'm sending this: ArrayList[ArrayList[Vertex3dDTO]] where Vertex3dDTO is an serializable object with contains float parameters. ArrayList[Vertex3dDTO] is contained in another serializable class Face3dDTO, and ArrayList[Face3dDTO] is in the serializable class Group3dDTO.
package com.nyquicksale.tailorapp.shared;
import java.io.Serializable;
public class Vertex3dDTO implements Serializable {
float x,y,z;
public Vertex3dDTO(){
}
public Vertex3dDTO(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
}
public class Face3dDTO implements Serializable {
ArrayList<Vertex3dDTO> vL = new ArrayList<Vertex3dDTO>();
Vertex3dDTO normal = new Vertex3dDTO();
Vertex3dDTO color = new Vertex3dDTO();
public Face3dDTO(){
}
public Face3dDTO(ArrayList<Vertex3dDTO> v) {
for(Vertex3dDTO v3dDTO : v){
vL.add(v3dDTO);
}
updateNormal();
}
public class Group3dDTO implements Serializable {
ArrayList<Face3dDTO> fL = new ArrayList<Face3dDTO>();
String name;
public Group3dDTO(){
}
public Group3dDTO(ArrayList<Face3dDTO> f) {
for(Face3dDTO f3dDTO : f){
fL.add(f3dDTO);
}
}
}
Now, everything is working well in development mode, but when I tested the application in hosted mode, everything I receive as response is: //OK[0,1, ["java.util.ArrayList/4159755760"],0,7]
So, I've been checked some other questions and seems the problem is about deserialization, but I've not found anything concrete.
The question is what do I have to do to get the app working well in hosted mode?
To successfully use RPC, your object needs to implement Serializable and should also have a default no arg constructor
Have you made sure this is a serialization problem? You can write a simple RPC test method to pass an array list of your DTO's over the wire in hosted mode.
If I were to bet money on a guess, I would say the problem is those array lists are sent empty in hosted mode. The .obj file read could be the problem. Perhaps in hosted mode the path of file doesn't match as in dev mode(different server configurations perhaps?), since file operations are in a try catch block an exception is most likely swallowed.
Long word short, Did you make sure those array lists are not sent empty in hosted mode?
Your object may well be Serializable, but that doesn't equate to something usable by Remote Procedure Calls. You need to implement Serializable, have a default contructor with no arguments (that calls super() if necessary), and a serial version ID, like so:
public class MyObject implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1796729355279100558L;
private Float someValue;
public MyObject() {
super();
}
public MyObject(Float someValue) {
super();
this.someValue = someValue;
}
public Float getSomeValue() {
return someValue;
}
public void setSomeValue(Float someValue) {
this.someValue = someValue;
}
}