I want to test SomeClass methods.
For that, I need SomeClass instance in every test so I'm using #Before annotation and initiate an instance of SomeClass named SC.
The problem is:- How can I test the constructor function after I already use it? It doesn't make sense.
Additional question:- The constructor can get number of arguments and they can influnce the methods outputs, should I mock this class instead of creating an instance of it?
public class SomeClassTest {
SomeClass SC;
#Before
public void initlize() throws IOException{
SC= new SomeClass (argument1,argument2,..);
}
#Test
public void ConstructorTest() {
}
Just don't use the object SC in your ConstructorTest. If you wan't to test a certain outcome from the construction of a SomeClass object with certain parameters then just construct it as such within your ConstructorTest and then assert the relevant outcomes you expect on the newly constructed object.
And no you shouldn't be mocking this class. The test is for testing this class so if you mock it's behaviour then you aren't really testing anything.
Related
I have a init() method that use injected private instance<>. How can I test this class using JUnit or Mockito? I tried to make some fake class and add them to a list and set this list to my private field but I have this error
java.lang.IllegalArgumentException: Can not set javax.enterprise.inject.Instance field ......
MyClass is:
#Singleton
#Startup
public class HandlerManager {
#Any
#Inject
private Instance<RollbackHandler<RollbackData>> handlers;
private RollbackHandler<RollbackData> rollbackHandler;
#PostConstruct
public void init() {
for (RollbackHandler<RollbackData> bean : handlers) {
//do something
}
}
}
Any annotation is not processed by frameworks, unless you use custom work. you will have to define all those dependencies as mocks in your test using #Mock and call injectMocks() from before test methods such as setup(). It is a multi part problem.
Use constructor injection, field injection is evil. you still will be able to annotate your constructor with #Inject.
when(provider.iterator()).thenReturn(list.iterator);
works for me.
You can create a temporary list with concrete implementations of the RollbackHandler, and mock the iterator() method of your Instance<RollbackHandler<RollbackData>> object so that it returns the iterator of the temporary list.
Example:
private void mockIterator() {
Instance<RollbackHandler<RollbackData>> handlers = mock(Instance.class);
List<RollbackHandler<RollbackData>> handlersList = Collections.singletonList(new RollbackHandlerImpl<>());
when(handlers.iterator()).thenReturn(handlersList.iterator());
}
I am having a hard time getting this one piece of mocking figured out for my unit tests. The classes in question are all part of legacy code that I don't really have the option of changing right now (I am hoping to be able to do some refactoring in the future, but need tests now).
Here are the two classes that I am dealing with, and the specific part I am having trouble with. Class A declares an object using new and then class B uses the object. I am trying to mock the object but I keep getting the real version of it instead of the mocked version.
public class B extends A(){
...
int x = problemObj.doMethod();
}
public class A(){
...
ProblemObj problemObj = new ProblemObj();
}
Here is my test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({A.class, B.class})
public class ATest(){
private ProblemObj problemObjMock;
#Before
public void setUp(){
problemObj = PowerMockito.Mock(ProblemObj.class);
}
#Test
public void test(){
PowerMockito.whenNew(ProblemObj.class).withNoArguments().thenReturn(problemObj);
...//rest of test below here
}
}
I have done other whenNew mocking in tests and set it up the same way as this. But for some reason this object being in the superclass is really throwing me off.
Versions used are Junit:4.11, Mockito:1.9.5, Powermock: 1.6.6
Is there an easy way, using Mockito, to load a mock class when another is requested OR to override the test ClassLoader?
Basically I have a class Foo that has a member "ClassA" in it. I want to replace to use "TestClassA" instead of "ClassA" during testing. I don't want to use dependency injection because it doesn't make any sense for actual operation. (It can never be anything other than ClassA)
Can I do this?
It can never be anything other than ClassA
...except that it is, in your test. Test code is real code, and though that doesn't mean it should sneak into your production application, it does mean that you need to write in the flexibility you need for all of its use cases, and that includes testing.
Mockito works via subclasses: A mockFoo created by mock(Foo.class) or #Mock Foo mockFoo is actually a proxy subclass Mockito created that overrides each of Foo's methods. As you can tell from that description, Mockito thus cannot change the behavior of every Foo object and especially cannot change the type of the object returned from new Foo().
You have two options, that I can see:
Accept a ClassA or InterfaceA instance in one of your constructors. If you put your tests in the same Java package as your class under test (even in a different source tree), you can even make the constructor package-private, or keep it private and create a static factory method like createForTest(ClassA).
Example:
public class ConsumerToTest {
private final ClassA classA;
/** For public use. */
public ConsumerToTest() {
this(new ClassA());
}
/** For use in tests. */
ConsumerToTest(ClassA class) {
this.classA = classA;
}
// ...
}
Use PowerMock, which has a Mockito integration known as PowerMockito. Though Mockito uses pure proxy subclasses and code generation, PowerMockito actually rewrites the bytecode of the system-under-test. This means that you can mock static methods and constructors that Mockito couldn't adjust on its own through polymorphism.
Personally, I very much prefer solution 1: The code is yours to control, and as long as you're clear that your test is a first-class consumer of your system-under-test, you're free to design it to be testable in the first place.
Doing it by constructor is what I prefer.
For example
public class Foo {
private ClassA classA;
public Foo(ClassA classA) {
this.classA = classA;
}
}
public class FooTest {
private Foo foo;
#before
public void setup() {
foo = new Foo(Mockito.mock(ClassA.class);
}
}
It's really simple to do this using Mockito.
public class Foo {
private ClassA classA;
}
Test will look like this:
#RunWith(MockitoJUnitRunner.class)
public class FooTest {
#Mock
private ClassA classA;
#InjectMocks
private Foo foo = new Foo();
//Test methods
}
That's it, you have mocked ClassA!
I am writing a TestNG testcase which extends atgdustcase. I need to mock a method in class B. This class B is injected into class A using properties file in ATG. Class C is a test class for testing functionality of class A. D is a test class which extends AtgDustCase.
#RunWith(PowerMockRunner.class)
#PrepareForTest({A.class, B.class})
Public class c extends D{
#InjectGlobalComponent(Path for component A)
#InjectMocks
private A aClass;
public void testMethod(){
String string = "abc";
Map map = new HashMap();
map.put("a", "c");
aClass = getRequest.resolveName(Component A path);
B b = PowerMockito.mock(B.class);
A a = PowerMockito.spy(new A());
PowerMockito.whenNew(A.class).withNoArguments().thenReturn(a);
a.setB(B);
PowerMockito.when(a.getB()).thenReturn(b);
Mockito.stub(b.getMethodToMock(string)).toReturn(map);
Mockito.verify(b).getMethodToMock(string);
aClass.invokeTestMethod();// This method calls the b.getMethodToMock()
}
}
I need to mock getMethodToMock(). When I execute invokeTestMethod(), this calls getMethodToMock(). At that time, map should be returned. Instead it is executing getMethodToMock() and it is throwing an error(The problem with execution is I need to fetch some records from DB. I need to mock this method and return a map which contains information retrieved from DB). I am not sure whether mocking is happening properly or not, as in debug mode I am able to see that the getMethodToMock() is getting invoked. Please help me how can I mock this method and skip the execution of this method.
Note: I tried using Powermockito, but my testcase is TestNGsuite. I need to run TestNGSuite instead of running it as Junit.
Hi I have a class which the invoke the run() method of a thread from the constructor of the class by calling the start() method , So please help me to Stubs the so to write the junit test cases . The class is as follows
public class MyClass extends Thread {
Student st=null;
University uni= new University();
public MyClass(Student st) {
this.st=st;
start();
}
public void run() {
uni.calculate(st);
}
}
Thanks
Take a look at the discussion here:
Testing Constructor With Powermock
It discusses sub-classing and overriding.
In general it should be considered bad practice to have to mock the class under test in order to test it. It is also hard to do since most mocking frameworks will not allow mocking a single method once in the class under test since they create wrapping proxies.