class GroovyHello {
public String execute() {
println("Test String is " + TEST)
}
private static final String TEST = "Test"
}
Output for the above snippet in Groovy V.1.6.3 is
Test String is Test
Output for the above snippet in Groovy V.1.8.6 is
Test String is null
The above snippet prints the string successfully if I modify the declaration to have either static (private static String TEST = "Test") or final (private final String TEST = "Test"), but not both.
My theory that since object Static and Private then you don't have access to it as it is a separate object. However if it is just private then your method is part of the object and it has access to it. If it is just static then you have access to the field - the field is public by default.
We noticed this happening when we had Groovy++ in the runtime classpath from other transitive dependencies. If that's the case, you might look at that.
Related
There is a third party java class in a library. Trying to extend that class in a Groovy Class. I would like to access that private property.
The problem is that it says
No such field: firstName for class: test2.Superuser
I am sure there must be a way to access the same and manipulate the property value using groovy.
Some posts suggests to use # before property name in order to access private property. But no luck.
Here is the sample code snippets.
User.java (a third party class of a library)
package test;
class User {
private String firstName;
private String name() {
firstName;
}
}
SuperUser.groovy (The one I am trying)
package test2
import test.User
class SuperUser extends User {
public static void main(String[] args) {
def suser = new SuperUser()
suser.#firstName = "John"
println suser.name()
}
}
Any help is appreciated.
Using below versions:
groovy : 1.8.0
jdk : 1.7.0
Java classes aren't able to access all of these private fields, properties and methods. It is only the other groovy scripts that are able to access it. The example below will demonstrate the same.
You should try to create both class file name as .groovy instead .java
User.groovy :
class User {
private String firstName;
private String name() {
firstName;
}
}
UserTest.groovy :-
class UserTest {
public static void main(String[] args) {
User user = new User();
user.#firstName = "John"
println user.name()
}
}
Output :- John
It's working fine with Java 8 and groovy-all-2.4.3
Note:- Follow this link for more details
Edited :- If you don't want to change super class because of third party code, you should try using java reflection to access private property of a class.
User.java is a Java class and not a Groovy class, so those variables are still private (unlike Groovy Variables which are always public to other Groovy classes).
So in the example above, unless the Java class includes some getters and setters, you will not be able to modify it's private members.
Maybe I'm late, but with your Java and Groovy version you can do the follow using meta programming:
package test2
import test.User
class SuperUser extends User {
public static void main(String[] args) {
def suser = new SuperUser()
User.metaClass.setProperty(suser,'firstName','John')
println User.metaClass.getMetaMethod('name',null).invoke(suser,null)
}
}
Or as other suggest in the traditional java reflection way:
package test2
import test.User
class SuperUser extends User {
public static void main(String[] args) {
def suser = new SuperUser()
def firstNameField = SuperUser.superclass.getDeclaredField('firstName')
firstNameField.setAccessible(true)
firstNameField.set(suser,"John")
def nameMethod = SuperUser.superclass.getDeclaredMethod('name')
nameMethod.setAccessible(true)
println nameMethod.invoke(suser,null)
}
}
How can I handle the String bundles, real one or faked?
I have a lots of cases affect each other of the String bundle, some legal codes write as below:
//example
private static I18n myInstance = I18n.getInstance().get(Example.class);
If all the cases run together, then this string bundle value will never reload because of it is static, actually different products have different string bundle values, then cause some case failed.
If not use the real string, the codes cannot run, because of the codes logic is base on the string bundle, seems only way is use real string bundle or fake the real value.
//example
if(isValue(myRB.getString("key")))
{
.....
}
You could inject the I18n instance into your class under test and mock I18n in the test.
public class YourClass {
private final I18n i18n;
public YourClass(I18n i18n) {
this.i18n = i18n;
}
}
I am trying to do some dependency injection for my tests using nUnit. I'm new to TDD and nUnit so it's possible I am missing something simple. So basically I've created a SetUp method for my interfaces. I originally was using a constructor but I read it's bad to do this when doing TDD so I now using a method.
When I run my test I construct an object and assign it to the interface and then I call a method using that interface. I want to test if it can parse a string decimal.
When I run my test it says test failed and the message is:Invalid signature for SetUp or TearDown method
See below for the actual code:
public class DonorTests
{
private IDonor _Donor;
private IValidateInput _ValidInput;
//DonorTests(IDonor donor, IValidateInput validInput)
//{
// _Donor = donor;
// _ValidInput = validInput;
//}
[SetUp]
void Setup(IDonor donor, IValidateInput validInput)
{
_Donor = donor;
_ValidInput = validInput;
}
[Test]
public void HandleStringNotDecimal()
{
_ValidInput = new ValidateInput();
Assert.IsTrue(_ValidInput.IsDecimal("3445.3450"));
}
}
My class that uses this interface
public class ValidateInput : IValidateInput
{
public decimal RoundTwoDecimalPlaces(decimal amount)
{
return Math.Round(amount);
}
public bool IsDecimal(string amount)
{
decimal ParsedDecimal;
return Decimal.TryParse(amount, out ParsedDecimal);
}
public decimal ConvertToString(string value)
{
decimal ParsedDecimal;
Decimal.TryParse(value, out ParsedDecimal);
return ParsedDecimal;
}
}
You're injecting dependencies using constructor injection previously, right? I think you will not be able to perform dependency injection using method decorated with SetUpAttribute because such method has to be parameterless. Also Setup method has to be public, see this SO thread.
How are we typically dealing with similar situations in our company is:
[TestFixture]
public class DonorTests
{
private IDonor _Donor;
private IValidateInput _ValidInput;
[SetUp]
public void Setup()
{
_Donor = new Donor();
_ValidInput = new ValidateInput();
}
[Test]
public void HandleStringNotDecimal()
{
Assert.IsTrue(_ValidInput.IsDecimal("3445.3450"));
}
}
Or if construction of ValidInput and Donor is cheap then we simply create new instance for each test, having special method for that purpose so when we decide to test another implementation of IValidateInput then it is enough to change it in one place only:
[TestFixture]
public class DonorTests
{
[Test]
public void HandleStringNotDecimal()
{
var validInput = CreateValidateInput();
Assert.IsTrue(validInput .IsDecimal("3445.3450"));
}
private static IValidateInput CreateValidateInput()
{
return new ValidateInput();
}
}
Besides the cause mentioned in the accepted answer, I have met the same error when leaving method as non-public (private or protected).
NUnit most probably relies on reflection and does not deal with non-public methods, so special methods (i.e. decorated with NUnit specific attributes) must be public.
I want to be sure that mocked is called with specific set of strings as parameter.
For example, I have the following code:
public class SomeLogic {
#Autowired
private SpecificService specificService;
public void action() {
Set<String> args = fillArgsMethod();
specificService.handleArgs(args);
}
}
And my current try to test it is the following
#Mock
private SpecificService specificService
#InjectMocks
private SomeLogic someLogic;
#Test
public void testAction() {
someLogic.action();
verify(specificService).handleArgs(anySet());
}
But I want to be sure, that handleArgs() will receive the exact set of strings, that I expect. How can I modify verifying to check that handleArgs is called with set "first","second"?
Thanks
Isah gave a valid answer, but I want to turn your attention to a more general feature of Mockito which is ArgumentCaptor
In you case you would do something along the following lines:
Class<HashSet<String>> setClass = (Class<HashSet<String>>)(Class)HashSet.class;
ArgumentCaptor<Set<String>> setCaptor= ArgumentCaptor.forClass(setClass .class);
verify(specificService).create(setCaptor.capture());
HashSet<String> capturedSet = setCaptor.getValue();
//do whatever test you want with capturedSet
Prepare your Set parameters before calling the test method
#Test
public void testAction() {
Set<String> expectedParams = new HashSet(Arrays.asList("first", "second");
//call tested method
verify(specificService).handleArgs(expectedParams);
}
isah's solution is perfect for you if you want to confirm that the set contains exactly the two items you specify; Mockito compares using .equals by default, and Set.equals is defined as refer to equal elements in any order.
For a more-flexible "contains" test that matches your question title, that allows for set members beyond your expected values, you can also use the Hamcrest contains matcher:
someLogic.action();
verify(specificService).handleArgs(argThat(contains("first", "second")));
At least, that's how it should look. Unfortunately, argThat infers its return type from the Matcher, which infers its return type from the arguments, so Java assumes your first argument is not a Set<String> but a Iterable<capture#1-of ? extends String>. You'll need to cast explicitly and suppress warnings to get it to work:
// requires #SuppressWarnings("unchecked")
verify(specificService).handleArgs(
(Set<String>) argThat(contains("first", "second")));
The code sample below indicates that you can call private methods using property notation, e.g. val instead of getVal(), and presumably val = "something" instead of setVal("something")
class Foo {
String foo = val
private getVal() { "val"}
}
assert new Foo().foo == "val"
I'm aware that this style is "officially supported" for public methods, but is it's use for private methods a bug/quirk, which one should rely on (much like the ability to access private members from outside a class)?
I've probably got the wrong end of the stick, but doesn't the same thing happen in Java...
Can't see how that differs from having:
class PrivateTest {
public String foo = getVal() ;
private String getVal() {
return "val" ;
}
}
and then the test class:
public class PrivateMain {
public static void main( String[] args ) {
PrivateTest pt = new PrivateTest() ;
System.out.println( pt.foo ) ;
}
}
The test class will still print out val
now that you mention it...
i don't remember how private members are handled.
but at least in the 1.8 instance i have running (no security manager in place), you can do things like
println new Date().fastTime
println new Date().normalize()
-- edit
i should really pay more attention
in your example, new Foo().foo is just accessing a standard groovy property.
new Foo().val or new Foo().getVal() on the other hand, would actually access the private members.
-- edit 2
wow. i truly didn't remember GROOVY-3010