I am trying to mock ThreadLocalRandom in my JUnit test.
#RunWith(PowerMockRunner.class)
public class SomeTest {
List<Game> games;
#Before
public void setUp() throws Exception {
mockStatic(ThreadLocalRandom.class);
when(ThreadLocalRandom.current()).thenReturn(any(ThreadLocalRandom.class));
when(ThreadLocalRandom.current().nextInt(any(Integer.class))).thenReturn(1);
games = Arrays.asList(new Game1(), new Game2());
}
#PrepareForTest({ ThreadLocalRandom.class })
#Test
public void someTestName() {
assertTrue(new Game(games).winner().equals(new Game1()));
}
}
While running the test I am getting error like,
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
Any input how to solve this?
public class Toss {
private final List<Game> games;
public Toss(List<Game> games) {
this.games = games;
}
public Game winner() {
return games.get(ThreadLocalRandom.current().nextInt(games.size()));
}
}
Any input what am I missing here?
The line
when(ThreadLocalRandom.current()).thenReturn(any(ThreadLocalRandom.class));
makes no sense. You can't tell Mockito (or PowerMock) to return just any old ThreadLocalRandom that it likes. You need to tell it which object to return. So instantiate ThreadLocalRandom and use the object that you create after thenReturn.
Related
I need to make validations on my custom ConstraintValidator that uses an #Inject needed for some validations, it's like this example from quarkus https://quarkus.io/guides/validation
#ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
#Inject
MyService service;
#Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return service.validate(value);
}
}
When i run the application I see that is made the right validation, but i'm trying to make unit test using mockito i can't mock the object is always null on the default using the Default Bean validation.
On the example from quarkus is unit test only for integration.
this is my implementation
#ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
#Inject
BookService service;
#ConfigProperty(name = "my.property")
int myLimit;
public MyConstraintValidator(BookService service) {
this.service = service;
}
#Override
public boolean isValid(String value, ConstraintValidatorContext context) {
System.out.println("myLimit property: " + myLimit);
int limit = Integer.parseInt(value);
if (limit < myLimit) {
return service.validate(value);
} else {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(NAME_EMPTY).addConstraintViolation();
return false;
}
}
}
Unit test for testing the custom Validator
#Test
void testAmountValidationWithContext() {
BookRequest bookRequest = new BookRequest();
bookRequest.setTitle("my title");
bookRequest.setAuthor("my Author");
bookRequest.setPages(2L);
bookRequest.setAmount("11");
//when:
myConstraintValidator = new MyConstraintValidator(service);
Mockito.when(service.validate(anyString())).thenReturn(true);
//then:
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
// verify that the context is called with the correct argument
Mockito.verify(context).buildConstraintViolationWithTemplate(NAME_EMPTY);
}
The unit test to test the default #NoBlank.
#Test
void testBeanValidationWithInvalidAmount() {
BookRequest bookRequest = new BookRequest();
bookRequest.setTitle("my title");
bookRequest.setAuthor("my Author");
bookRequest.setPages(2L);
bookRequest.setAmount("AA");
//when:
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
//then:
assertEquals(1, violations.size());
assertEquals(NOT_EMPTY, violations.stream().findFirst().get().getMessage());
}
The first unit test works weel, i can mock the object and test the result.
The problem is on my second test, when i try to test the other validations #NotNull, #Pattern. On this test the method isValid() is also invoked and here it's my problem because the #ConfigProperty and the #Inject are always null, and i can't mocked them.
I already saw several examples over internet but doesn't work and are almost for spring but i need to make the custom validation on quarkus.
How can i implement the custom ConstraintValidator unit test using quarkus?
Does any one have any example with this working?
Changing your code from field injection to constructor injection will make unit testing much easier.
#ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
private final MyService service;
private final int myLimit;
public MyConstraintValidator(MyService service, #ConfigProperty(name = "my.property") int myLimit) {
this.service = service;
this.myLimit = myLimit;
}
#Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
if (value == null) {
return true;
}
return service.validate(value);
}
}
Updated description with my implementations.
but resuming the issue.
when i have the default annotations with my custom validator i can't mock the objects using the
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
I just converted our application code into simple classes to express the problem concisely. Our use case contains a class which internally uses some helper classes with static methods which needs to be mocked. So, planned to use PowerMockito. No issues with this part, however we have one class where we have an anonymous block inside one of the methods. When we try to create an instance of this class, PowerMockito fails with a very vague error. Tried spending few hours to resolve the issue without any luck.
public abstract class AbstractClass {
public abstract void methodOne(String arg);
public void methodTwo()
{
System.out.println("In method two");
}
}
public class StaticMethod {
public static String someStaticMethod()
{
System.out.println("in static method");
return "static";
}
}
public class AbstractClassCaller {
public AbstractClassCaller()
{
StaticMethod.someStaticMethod();
// The following piece of code is the problematic block
AbstractClass abstractClassInstance = new AbstractClass(){
public void methodOne(String methodArg)
{
System.out.println("In Method One");
}
};
}
}
#Test
#PrepareForTest({AbstractClassCaller.class,StaticMethod.class})
public class AbstractClassCallerTest {
#Test
public void test() throws Exception
{
PowerMockito.mockStatic(StaticMethod.class);
PowerMockito.when(StaticMethod.someStaticMethod()).thenReturn(
"PowerStatic");
// This is the code which triggers the exception
AbstractClassCaller instance = new AbstractClassCaller();
}
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
}
The above junit class fails with the following exception:
org.powermock.reflect.exceptions.ConstructorNotFoundException: Failed to lookup constructor with parameter types [ com.oracle.oal.seaas.AbstractClassCaller ] in class com.oracle.oal.seaas.AbstractClassCaller$1.
at com.oracle.oal.seaas.AbstractClassCallerTest.test(AbstractClassCallerTest.java:21)
Caused by: java.lang.NoSuchMethodException: com.oracle.oal.seaas.AbstractClassCaller$1.<init>(com.oracle.oal.seaas.AbstractClassCaller)
at com.oracle.oal.seaas.AbstractClassCallerTest.test(AbstractClassCallerTest.java:21)
// the following anonymous block in AbstractClassCaller is causing the issue:
AbstractClass abstractClassInstance = new AbstractClass(){
public void methodOne(String methodArg)
{
System.out.println("In Method One");
}
};
Any ideas on how to fix this issue?
I'm trying to implement a Contract test on Java as described there.
I paste the first test's code in my project and changed import static net.corda.testing.NodeTestUtils.ledger; to import static net.corda.testing.node.NodeTestUtils.ledger;
package com.template;
import org.junit.Test;
import static net.corda.testing.node.NodeTestUtils.ledger;
public class CommercialPaperTest {
#Test
public void emptyLedger() {
ledger(l -> {
return null;
});
}
}
And I see that ledger method has an absolutely different signature, so Java says that it cannot resolve method ledger(<lambda expression>).
What am I doing wrong?
There is an error on that page. The first argument to ledger should be a MockServices instance.
For example, we might write:
public class CommercialPaperTest {
private static final TestIdentity megaCorp = new TestIdentity(new CordaX500Name("MegaCorp", "London", "GB"));
private MockServices ledgerServices;
#Before
public void setUp() {
ledgerServices = new MockServices(
singletonList("net.corda.finance.contracts"),
megaCorp,
makeTestIdentityService(megaCorp.getIdentity())
);
}
#Test
public void emptyLedger() {
ledger(ledgerServices, l -> {
return null;
});
}
}
I have two fields that are connected with master-slave relationship :
public class Slave extends AbstractListBox<String> {
#Override
protected Class<? extends IValueField> getConfiguredMasterField() {
return Master.class;
}
#Override
protected void execChangedMasterValue(final Object newMasterValue) {
this.function() // -> here I put debugging break point
}
}
public class Master extends AbstractBooleanField {
#Override
protected void execChangedValue() {
super.execChangedValue(); // -> Break point 2
}
}
I write unit test for this relationship, but inside unit test execChangedMasterValue is never called.
My unit test looks like :
#Test
public void test() {
this.box.getMaster.setValue(true)
Assert.assertFalse(... something from function Slave ...)
}
Unit tests always failed, and if I put breakpoints as described above, debugger stops only on second break point but never on first one.
In "real" world, function is called and everything works as it should.
Is there a reason that execChangedMasterValue is not called? Is behaviour of execChangedMasterValue different from changedValue()?
I cannot reproduce what you are describing. I took the Scout HelloWorld Project (the one that is generated when you create a new project).
In the HelloWorldForm I have added this "slave" field in the MainBox:
#Order(2000)
public class LengthField extends AbstractIntegerField {
#Override
protected String getConfiguredLabel() {
return TEXTS.get("Length");
}
#Override
protected Class<? extends IValueField<?>> getConfiguredMasterField() {
return MessageField.class;
}
#Override
protected void execChangedMasterValue(Object newMasterValue) {
if(newMasterValue instanceof String) {
String s = (String) newMasterValue;
setValue(s.length());
} else {
setValue(0);
}
}
}
And in the example Unit Test HelloWorldFormTest, I have added an additional check to testMessageCorrectlyImported():
/**
* Tests that the {#link MessageField} is correctly filled after start.
*/
#Test
public void testMessageCorrectlyImported() {
HelloWorldForm frm = new HelloWorldForm();
frm.start();
Assert.assertEquals("Message field", MESSAGE_VALUE, frm.getMessageField().getValue());
Assert.assertEquals("Length field", Integer.valueOf(MESSAGE_VALUE.length()) , frm.getLengthField().getValue());
frm.getMessageField().setValue("abcdef");
Assert.assertEquals("Length field (after update)", Integer.valueOf("abcdef".length()), frm.getLengthField().getValue());
}
Everything works as expected…
I am trying to write an integration test using AbstractTransactionalJUnit4SpringContextTests. I want to use executeSQLScript method of this class.
However, when executeSQLScript method is called, it throws NullPointerException because simpleJdbcTemplate parameter of class AbstractTransactionalJUnit4SpringContextTests is not getting initialized.
My code looks as given below:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"classpath:test-services-spring-context.xml"})
#TransactionConfiguration(transactionManager = "promoTransactionManager")
public class PromoBrickDAOIT extends AbstractTransactionalJUnit4SpringContextTests {
#Autowired
private PromoBricksDAO promoBricksDAO;
#Before
public void setUp(){
executeSqlScript("classpath:testdata/sql/PromoBrick_Create.sql", false);
}
#After
public void tearDown(){
}
#Test
public void testPromoBrickGivenBrowseTaxonomyNodeId(){
String btxNodeId = "v1_12";
List<PromoBrick> promoBricks = promoBricksDAO.findByBtxNodeId(btxNodeId);
assertNotNull(promoBricks);
assertEquals(promoBricks.size(), 1);
PromoBrick promoBrick = promoBricks.get(0);
assertNotNull(promoBrick);
}
public void setDataSource (#Qualifier("promoDataSource") DataSource dataSource) {
super.setDataSource(dataSource);
}
}
Thanks in advance for the help!
You're missing #Autowired on your setDataSource() method.
See the last NOTE in the Dependency injection of test fixtures section of the Spring Reference Manual.