Testing an injected config with spring without spring test runner - testing

Given the following class:
public class ClassToBeTest{
${property.utility}
private String property;
private Utility utility;
public ClassToBeTested(Utility utility){
this.utility = utility;
}
public void doSomething(){
utility.doSomething(property);
}
}
We want to Mock Utility (we are using Mockito for instance) and verify that utility.doSomething is called passing the property parameter.
We don't really care about the config value (we have other tests for that). But we don't want to open the class with a method like (or passing the property by constructor).
public void setPropertyForTest(String property){
this.property = property;
}
Is there other ways to check that this private property (with no value) is passed to Utility?
Thanks a lot.

If you just want to set the private field, Spring (not Sprint) provides support for that in the spring-test module. See the setField() variants in ReflectionTestUtils.
Regards,
Sam

Related

How to add global values in .NET Core 3?

I need to set global values and read it from anywhere in my project.
what is the scenario, if AddSingleton how?
I have seen this, but it's not working for me:
Global Variables in ASP.Net Core 2
The answer from Noah is very good, however for simpler cases you generally want to:
Create a static class that holds all your data, in the root namespace
public static class Cache
{
public static string Value1 => "Example";
public static int Value2 => 42;
}
Done
You can access it's values system-wide, like so:
var mySharedStringValue = Cache.Value1;
If you need to "load" those values in the startup, you can change the signature of the properties to
public static string Value1 { get; private set; }
and use a static constructor or a simple static initialization method that you call in the Startup.cs class when the APP is starting.
If you want to read a static value globally, I'd suggest using the configuration system for that. It allows injecting the configuration wherever needed for reading.
If you need to share data that can change, you need some shared thread-safe mechanism. One option built into the framework is to use the in-memory cache, which is a global shared cache injectable anywhere.

Autofac Register closed types and retrieve them at run time

I have an Interface that will take in a generic type T
internal interface IQuestion<T> where T : IWithOptionsId
{
Task<T> Provide(Guid id);
}
Following by that I will implement this interface in multiple classes. For example
public class SomeProvider : IQuestion<OptionsClass>
{
private readonly IRepository _repository;
public SomeProvider(IRepository repository)
{
_repository = repository;
}
public async Task<OptionsClass> Provide(Guid id)
...
}
To register this with outofac I used this
Autofac.RegisterAssemblyTypes(
Assembly.GetExecutingAssembly())
.AsImplementedInterfaces()
.AsClosedTypesOf(typeof(IQuestion<>));
My question is this. I have multiple instances for this interface. How do I access different instance once at the run time? If my IQuestion<T> will take in Options class and also it will take in Answer class how can I get an instance of those classes during run time?
I'm pretty sure you can just inject the instance itself. Not great practice, but it should work:
public SomeClass(SomeProvider<OptionsClass> provider)
You could also try creating a named instance when you register it, and inject that. See this and this.

JavaFX Wrap an Existing Object with Simple Properties

I am writing a new app and I have chosen to use Java for flexibility. It is a GUI app so I will use JavaFX. This is my first time using Java but I have experience with C#.
I am getting familiar with JavaFX Properties, they look like a great way of bi-directional binding between front-end and back-end.
My code uses classes from an open-source API, and I would like to convert the members of these classes to JavaFX Properties (String => StringProperty, etc). I believe this would be transparent to any objects that refer to these members.
Is it ok to do this?
Is it the suggested way of dealing with existing classes?
What do I do about Enum types? E.g. an enum member has it's value changed, how should I connect the enum member to the front-end?
Thank you :)
In general, as long as you don't change the public API of the class - in other words you don't remove any public methods, modify their parameter types or return types, or change their functionality - you should not break any code that uses them.
So, e.g. a change from
public class Foo {
private String bar ;
public String getBar() {
return bar ;
}
public void setBar(String bar) {
this.bar = bar ;
}
}
to
public class Foo {
private final StringProperty bar = new SimpleStringProperty();
public StringProperty barProperty() {
return bar ;
}
public String getBar() {
return barProperty().get();
}
public void setBar(String bar) {
barProperty().set(bar);
}
}
should not break any clients of the class Foo. The only possible problem is that classes that have subclassed Foo and overridden getBar() and/or setBar(...) might get unexpected behavior if their superclass is replaced with the new implementation (specifically, if getBar() and setBar(...) are not final, you have no way to enforce that getBar()==barProperty().get(), which is desirable).
For enums (and other objects) you can use an ObjectProperty<>:
Given
public enum Option { FIRST_CHOICE, SECOND_CHOICE, THIRD_CHOICE }
Then you can do
public class Foo {
private final ObjectProperty<Option> option = new SimpleObjectProperty<>();
public ObjectProperty<Option> optionProperty() {
return option ;
}
public Option getOption() {
return optionProperty().get();
}
public void setOption(Option choice) {
optionProperty().set(choice);
}
}
One caveat to all this is that you do introduce a dependency on the JavaFX API that wasn't previously present in these classes. JavaFX ships with the Oracle JDK, but it is not a full part of the JSE (e.g. it is not included in OpenJDK by default, and not included in some other JSE implementations). So in practice, you're highly unlikely to be able to persuade the developers of the open source library to accept your changes to the classes in the library. Since it's open source, you can of course maintain your own fork of the library with JavaFX properties, but then it will get tricky if you want to incorporate new versions of that library (you will need to merge two different sets of changes, essentially).
Another option is to use bound properties in the classes, and wrap them using a Java Bean Property Adapter. This is described in this question.

how to mock a class's inner static class's private field

i'm test a MR class which has mapper/reducer as inner static classes. the mapper has a private field which consume too much memory to make the test failed, i want to use a mock object for that field, but not sure how to do that, here is my code:
public class Aggregator extends Configured implements Tool {
public static class AggregatorMapper extends Mapper<LongWritable, Text, GeneralKey, Text) {
private LookupService lookupService = null; <--- the object i want to mock
}
}
i tried to mockito but seems no way to mock it. any suggestions? thanks!
You can use reflection to access and modify any property of any object you want. There are several questions on SO that answer this quite well already, for example:
Change private static final field using Java reflection.
Accessing private variables in Java via reflection
Instantiate private inner class with java reflection

wicket and AtUnit

I've started playing with Wicket and I've chosen Guice as dependency injection framework. Now I'm trying to learn how to write a unit test for a WebPage object.
I googled a bit and I've found this post but it mentioned AtUnit so I decided to give it a try.
My WebPage class looks like this
public class MyWebPage extends WebPage
{
#Inject MyService service;
public MyWebPage()
{
//here I build my components and use injected object.
service.get(id);
....
}
}
I created mock to replace any production MyServiceImpl with it and I guess that Guice in hand with AtUnit should inject it.
Now the problems are:
AtUnit expects that I mark target object with #Unit - that is all right as I can pass already created object to WicketTester
#Unit MyWebPage page = new MyWebPage();
wicketTester.startPage(page);
but usually I would call startPage with class name.
I think AtUnit expects as well that a target object is market with #Inject so AtUnit can create and manage it - but I get an org.apache.wicket.WicketRuntimeException: There is no application attached to current thread main. Can I instruct AtUnit to use application from wicketTester?
Because I don't use #Inject at MyWebPage (I think) all object that should be injected by Guice are null (in my example the service reference is null)
I really can't find anything about AtUnit inside Wicket environment. Am I doing something wrong, am I missing something?
I don't know AtUnit but I use wicket with guice and TestNG. I imagine that AtUnit should work the same way. The important point is the creation of the web application with the use of guice.
Here how I bind all this stuff together for my tests.
I have an abstract base class for all my tests:
public abstract class TesterWicket<T extends Component> {
#BeforeClass
public void buildMockedTester() {
System.out.println("TesterWww.buildMockedTester");
injector = Guice.createInjector(buildModules());
CoachWebApplicationFactory instance =
injector.getInstance(CoachWebApplicationFactory.class);
WebApplication application = instance.buildWebApplication();
tester = new WicketTester(application);
}
protected abstract List<Module> buildModules();
The initialization is done for every test class. The subclass defines the necessary modules for the test in the buildModules method.
In my IWebApplicationFactory I add the GuiceComponentInjector. That way, after all component instantiation, the fields annotated with #Inject are filled by Guice:
public class CoachWebApplicationFactory implements IWebApplicationFactory {
private static Logger LOG = LoggerFactory.getLogger(CoachWebApplicationFactory.class);
private final Injector injector;
#Inject
public CoachWebApplicationFactory(Injector injector) {
this.injector = injector;
}
public WebApplication createApplication(WicketFilter filter) {
WebApplication app = injector.getInstance(WebApplication.class);
Application.set(app);
app.addComponentInstantiationListener(new GuiceComponentInjector(app, injector));
return app;
}
}