Here's my problem in detail.
Setup:
I have class A that has a private member variable of class B.
A method(method1) in class A calls a non-static method(method2)
in class B.
Class B actually inherits method2 from a protected abstract class C and does not override it.
Problem:
I'm writing a test for class A.
In the test I'm mocking the call to method2.
Sample Code:
B b = Mockito.mock(B.class);
A a = new A(b);
Mockito.when(b.method2()).thenReturn(MY_LIST);
Now when I call method1(which in turn calls method2), I get a
NullPointerException.
Sample Code:
a.method1();
I'm assuming that this call is completely independent of the implementation of method2 since I'm mocking it. Is that wrong ? If not, what am I doing wrong ?
PS: class C is protected and Class A is in a different package from class B and C.
I see that you are using Mockito in your test. I have recently used it on a project and I did a test project with the following.
First a service (A) with uses another class (B).
public class Service {
private NonStaticClass nonStatic;
public NonStaticClass getNonStatic() {
return nonStatic;
}
public void setNonStatic(NonStaticClass nonStatic) {
this.nonStatic = nonStatic;
}
public int useStaticService () {
return 2*StaticClass.staticMethod();
}
public Integer getLastUse () {
return this.nonStatic.getLastUse();
}
}
Then here is the (B) class:
public class NonStaticClass {
private Integer lastUse = new Integer(0);
public Integer getLastUse() {
return lastUse++;
}
}
In order to test everithing is working i created a test for it.
import static org.mockito.Mockito.when;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class TestNonStaticMock {
private final Integer staticMethodOutput = 10;
#Mock
NonStaticClass mock = new NonStaticClass();
#InjectMocks
Service service = new Service();
#Before
public void before () {
setMock();
}
private void setMock() {
when(mock.getLastUse()).thenReturn(staticMethodOutput);
}
#Test
public void mockNonStaticMethod () {
Integer result = service.getLastUse();
System.out.println(result.toString());
Assert.assertEquals(staticMethodOutput, result);
}
}
Hope it can be usefull.
Related
I can’t figure out how I can block the call to the B setTitle method so that it does nothing, but for example just output to the console (output from the system)?
In method B setTitle an error appears, but I want the tests to be independent and the error to be in the class with the test for B
#Component
class B {
public setTitle(String s){
...
}
}
#Service
class A {
#Autowired
private B b;
public getTitle(String s){
b.setTitle(s);
}
}
class ATest {
#Autowired
private class A;
#Test
void getTitleTest() {
//TODO how to override the call class B getTitle
}
}
First off, note that there is a lot of issues with what you have posted here.
You have methods declared without return types, getters that perform mutations, and trying to Autowire private class.
To answer your question, what you want to do is create a Mock and run this with a MockRunner.
Here is a test that will verify the method in your class B was invoked as you expected.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
private B b;
#InjectMocks
private A a;
#Test
public void getTitleTest() {
a.getTitle("soemthing");
Mockito.verify(b).setTitle("soemthing");
}
}
If you indeed want it to print something to the console, you can change the test method by capturing the argument to the method and simply printing it out, like this:
#Test
public void titleTester() {
ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
doNothing().when(b).setTitle(stringArgumentCaptor.capture());
a.getTitle("soemthing");
System.out.println(stringArgumentCaptor.getValue());
}
I have a class which I would like to test with a public method that calls private one. I'd like to assume that private method works correctly. For example, I'd like something like doReturn....when.... I found that there is possible solution using PowerMock, but this solution doesn't work for me.
How It can be done? Did anybody have this problem?
I don't see a problem here. With the following code using the Mockito API, I managed to do just that :
public class CodeWithPrivateMethod {
public void meaningfulPublicApi() {
if (doTheGamble("Whatever", 1 << 3)) {
throw new RuntimeException("boom");
}
}
private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}
And here's the JUnit test :
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
#RunWith(PowerMockRunner.class)
#PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {
#Test(expected = RuntimeException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
.withArguments(anyString(), anyInt())
.thenReturn(true);
spy.meaningfulPublicApi();
}
}
A generic solution that will work with any testing framework (if your class is non-final) is to manually create your own mock.
Change your private method to protected.
In your test class extend the class
override the previously-private method to return whatever constant you want
This doesn't use any framework so its not as elegant but it will always work: even without PowerMock. Alternatively, you can use Mockito to do steps #2 & #3 for you, if you've done step #1 already.
To mock a private method directly, you'll need to use PowerMock as shown in the other answer.
For some reason Brice's answer is not working for me. I was able to manipulate it a bit to get it to work. It might just be because I have a newer version of PowerMock. I'm using 1.6.5.
import java.util.Random;
public class CodeWithPrivateMethod {
public void meaningfulPublicApi() {
if (doTheGamble("Whatever", 1 << 3)) {
throw new RuntimeException("boom");
}
}
private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}
The test class looks as follows:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.doReturn;
#RunWith(PowerMockRunner.class)
#PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {
private CodeWithPrivateMethod classToTest;
#Test(expected = RuntimeException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
classToTest = PowerMockito.spy(classToTest);
doReturn(true).when(classToTest, "doTheGamble", anyString(), anyInt());
classToTest.meaningfulPublicApi();
}
}
i know a way ny which you can call you private function to test in mockito
#Test
public void commandEndHandlerTest() throws Exception
{
Method retryClientDetail_privateMethod =yourclass.class.getDeclaredMethod("Your_function_name",null);
retryClientDetail_privateMethod.setAccessible(true);
retryClientDetail_privateMethod.invoke(yourclass.class, null);
}
With no argument:
ourObject = PowerMockito.spy(new OurClass());
when(ourObject , "ourPrivateMethodName").thenReturn("mocked result");
With String argument:
ourObject = PowerMockito.spy(new OurClass());
when(ourObject, method(OurClass.class, "ourPrivateMethodName", String.class))
.withArguments(anyString()).thenReturn("mocked result");
Something to Consider
Make sure the private function is calling another public function and you can proceed only mocking the public function.
Hi I have the following classes
public class DataAccessLayer<T> {
public T getData(Class<?> dataInfoType ,Integer id){
//Some logic here
}
}
public class ServiceLayer{
//this method has to be tested
public Integer testingMethode{
//The following line should be mocked
UtilClass info = new DataAccessLayer<UtilClass>().getData(UtilClass.class, 1);
retutn info.getSomeFieldWithIntegerValue();
}
}
I want to write test cases for testingMethode for that I need to mock the getData() method in DataAccessLayer<T>
Is it possible with jmockit to mock a Template(Generic ) class?
A generic class can be mocked the same way a non-generic one:
#Test
public void example(#Mocked final DataAccessLayer<UtilClass> mock)
{
final UtilClass data = new UtilClass(123);
new Expectations() {{ mock.getData(UtilClass.class, 1); result = data; }};
int result = new ServiceLayer().testingMethode();
assertEquals(123, result);
}
(I can only really answer for Mockito, as that is what I am most familiar with; but the same principle should be applicable in other mocking frameworks).
Firstly, you need to be able to inject a DataAccessLayer<UtilClass> into ServiceLayer, e.g.
class ServiceLayer {
private final DataAccessLayer<UtilClass> dal;
ServiceLayer(DataAccessLayer<UtilClass> dal) {
this.dal = dal;
}
public Integer testingMethode() {
UtilClass info = dal.getData(UtilClass.class, 1);
return info.getSomeFieldWithIntegerValue();
}
}
This breaks the static coupling to the DataAccessLayer<UtilClass> created by the use of the new.
Now, you can create a mocked instance of DataAccessLayer<UtilClass> by creating a non-generic subclass:
class UtilClassDataAccessLayer extends DataAccessLayer<UtilClass> {}
and then create a mock instance:
DataAccessLayer<UtilClass> mocked = mock(UtilClassDataAccessLayer.class);
Now, you can configure this mock as you need, and pass it into the ServiceLayer:
ServiceLayer serviceLayer = new ServiceLayer(mocked);
In JMockit there's actually no need to create a holding variable in the ServiceLayer class, nor is there a need to make a parameterized subclass of your DataLayer. The following test works just fine:
package com.example.dsohl;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Mocked;
import mockit.Tested;
import mockit.integration.junit4.JMockit;
#RunWith(JMockit.class)
public class TestTest {
public static class UtilClass {
public Integer foo() {
return 5;
}
}
public static class DataLayer<T> {
public T getItem(Class<T> clazz, int itemId) {
return null;
}
}
public static class ServiceLayer {
public Integer testMethod() {
UtilClass util = new DataLayer<UtilClass>().getItem(UtilClass.class, 1);
return util.foo();
}
}
// Test really begins here
#Tested ServiceLayer svc;
#Mocked DataLayer<UtilClass> data;
#Mocked UtilClass util;
#Test
public void testDateSubtraction() throws Exception {
new Expectations() {
{
new DataLayer<UtilClass>(); result = data;
onInstance(data).getItem(UtilClass.class, 1); result = util;
util.foo(); result = 37;
}
};
Integer i = svc.testMethod();
assertThat(i, equalTo(37));
}
}
A few notes: First, my DataLayer.getItem() returns null so if the injection fails, we get a NullPointerException, nice and obvious. Obviously your code won't work like this; this is only to convince you.
Second, I use onInstance() so that we can be 100% certain that the result of the DataLayer constructor is what we are using in the next steps of the test. The default behaviour of Expectations on a #Mocked object is to record the expectation against any object of that class; this is how we are certain that it's our object that's being used. (Ordinarily I don't worry myself about this, but when using new I like to be certain.)
Finally, I'm omitting some other stuff I might do in cases like this, like use a Verifications block, etc. Just trying to be as straightforward as possible.
Enjoy!
I´m using google guice to inject this class example
class A {
String a;
}
Then is injected in my class B
class B {
#Inject A aInstance;
public void checkValue(){
System.out.println(aInstance.a);
}
}
Maybe using aspectJ, but what I would like is, that one test of mine, would get this A instance and would set the "a" string as "foo", before execute the test that cover the B class, so when the B class invoke checkValue this one would print "foo"
You mention the word test in your question - if you are writing a jUnit test for B you could perform the injection in an #Before clause, as demonstrated here.
private Injector injector;
#Before
public void init() throws Exception {
injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(A.class).to(MockedInstanceOfAWithValueFoo.class);
}
});
}
You could also call
bind(A.class).toInstance(new MockedInstanceOfAWithValueFoo());
If we assume that A has a constructor by which we can define A.a, the mocked instance could look like this:
public class MockedInstanceOfAWithValueFoo extends A{
public MockedInstanceOfAWithValueFoo() {
super("foo");
}
}
Again, you could make your mocked class accept the value of A.a through a constructor to make the creation of B (and the associated value of A.a) more dynamic.
With Mockito:
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class MyTest {
#Mock
A mockA;
#InjectMocks
B mockB;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
mockA.a = "Foo";
//when(mockA.getA()).thenReturn("Foo"); //if you use getter
}
#Test
public void myTest() {
assertNotNull(mockA);
assertNotNull(mockA.a);
assertNotNull(mockB);
assertNotNull(mockB.ainstance);
mockB.checkValue();
}
}
I'v a base class which has selenium configuration for the application. I want to use the class A(selenium configuration.class) to another class B(Action.class) which is again has to extend Class c(UIElemnts.class).
I tried to user Google guice to bind the classes like this.
how should I use two classes (A& C) on class B using Google Guice. Kindly explain with example
In this example I want to use the setup method and driver object in class B but class B is already extended to Class. I just want to try Google Guice to bind the classes.
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.Proxy.ProxyType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.testng.annotations.BeforeTest;
import test.com.x.software.b.base.SeleniumConfiguration;
import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Singleton;
import com.thoughtworks.selenium.SeleneseTestBase;
public class SeleniumConfiguration extends SeleneseTestBase{
public static WebDriver driver;
#BeforeTest
public static void setup() {
// Invoking firefox browser
FirefoxProfile firefoxobj = new FirefoxProfile();
firefoxobj.setPreference("network.proxy.type",
ProxyType.AUTODETECT.ordinal());
// System.out.println("********************");
driver = new FirefoxDriver(firefoxobj);
// System.out.println("********************"+Url);
driver.navigate().to("https://software.x.com");
// System.out.println("********************");
driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
}
}
public class class B extends Class C{
# Test
public static void createDeveloper() throws InterruptedException
{
// String currentdate=dateFormatting();
// String firstname="Test_Fn_"+currentdate;
// String lastname ="Test_Ln_"+currentdate;
// String loginid="Test_Tp_"+currentdate;
}
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Class C extends PageFactory {
}
It is not entirely clear to me what problem you are trying to solve. If you have class B and want to use the methods of two different classes (A and C) in class B, then it looks like you just need to declare the dependency of class B on class A and C and then either delegate public methods to the underlying class A and C or use the methods internally in class B. Here is a SSCE:
public class SO24278992 {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
// Different concrete instances of A and C
// could be used here.
//
// Alternatively, you don't need these explicit
// bindings at all if the default contstructor
// does everything you need and you are not
// requiring explicit bindings.
bind(A.class).toInstance(new A());
bind(C.class).toInstance(new C());
}
});
B b = injector.getInstance(B.class);
b.useA();
b.useC();
}
static class B {
private A classA;
private C classC;
#Inject
public B(A a, C c) {
this.classA = a;
this.classC = c;
}
public void useC() {
classC.doSomething();
}
public void useA() {
classA.doSomethingElse();
}
}
static class A {
public void doSomethingElse() {
System.out.println("Doing something else in A");
}
}
static class C {
public void doSomething() {
System.out.println("Doing something in C");
}
}
}
I am not sure if this is what you are talking about though.
chooks
I was trying to implement something like the below one.not sure how did they implement it.
(http://testng.org/doc/documentation-main.html)
5.18.2 - Guice dependency injection
If you use Guice, TestNG gives you an easy way to inject your test objects with a Guice module:
#Guice(modules = GuiceExampleModule.class)
public class GuiceTest extends SimpleBaseTest {
#Inject
ISingleton m_singleton;
#Test
public void singletonShouldWork() {
m_singleton.doSomething();
}
}
In this example, GuiceExampleModule is expected to bind the interface ISingleton to some concrete class:
public class GuiceExampleModule implements Module {
#Override
public void configure(Binder binder) {
binder.bind(ISingleton.class).to(ExampleSingleton.class).in(Singleton.class);
}
}
Refernce: Copied from testng.org