Change value of guice instance on runtime - java

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();
}
}

Related

Mocking Autowire in a class

I have an XYZ class which is autowired in ABC and in class MyClass I have a method name doSomething() inside that method I do ABC abc = new ABC(); Then I call abc.someMethod();
Please see code sample below :
Class ABC
public class ABC {
#Autowire
private XYZ xyz;
public void someMethod()
{
//Some stuff
xyz.someFunc();
}
}
Class MyCLass
public class MyCLass {
public void doSomething() {
ABC abc = new ABC();
abc.someMethod();
}
}
Need unit test doSomething() but I NPE as XYZ is null in ABC. How can I mock #Autowire in this case.
If you use constructor injection instead of field injection, you can create the mock and give it to the constructor of ABC:
public class ABC {
private final XYZ xyz;
public ABC(XYZ xyz) {
this.xyz = xyz;
}
public void someMethod()
{
//Some stuff
xyz.someFunc();
}
}
Then in your test, when you create the instance under test, you just create it and hand over the mock:
XYZ mock = mock(XYZ.class);
ABC underTest = new ABC(mock);
You can use the following testing capabilities in your test:
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
Provide a configuration and use it, for example:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = MyTest.MyTestConfiguration.class)
public class MyTest {
// xyz injected into ABC and MyTest for convenience.
#Autowired
private XYZ xyz;
#Test
public void myTest() {
// Some Stubbing...
when(xyz.trySomething()).thenReturn(true);
// Some verification.
new ABC().doSomething();
verify(xyz, times(1))
.trySomething();
}
// Note it is used in #ContextConfiguration
#Configuration
static class MyTestConfiguration {
#Bean
XYZ xyz() {
return mock(XYZ.class);
}
}
}
The documentation is a bit extensive, search for the mentioned annotations here https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#integration-testing

How to override the call (junit5)?

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());
}

How to test java class having initialisation in constructor

I have a java class whose constructor looks like this
private SomeManager someManager;
public MyService() {
this.someManager = ManagerHandler.getDefault();
}
The issue is that while testing ManagerHandler is not initialised so I am not able to create new object of this class to test its method. I am using mockito for testing. I am not able to understand How to mock a parameter which I am not passing in the constructor.
Is there anyway I can mock someManager using PowerMock?
You can use InjectMocks annotation. See below example:
MyService class:
public class MyService {
ManagerHandler someManager;
public MyService() {
this.someManager = ManagerHandler.getDefault();
}
// other methods
public String greetUser(String user) {
return someManager.sayHello(user) + ", Good Morning!";
}
}
ManagerHandler class:
public class ManagerHandler {
public static ManagerHandler getDefault() {
return new ManagerHandler();
}
public String sayHello(String userName) {
return "Hello " + userName;
}
}
TestClass:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class TestClass {
#Mock
ManagerHandler someManager;
#InjectMocks
MyService myService = new MyService();
#Test
public void test() {
//mock methods of ManagerHandler
Mockito.when(someManager.sayHello("Alice")).thenReturn("Hello Alice");
assertEquals("Hello Alice, Good Morning!", myService.greetUser("Alice"));
}
}

Mocking method from protected abstract method

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.

How to bind two classes into one classes using google guice?

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

Categories