Where should i put classes only used for development? - java

I started using dependency injection with roboguice and created an interface like DataProvider. I have an implementation which retrieves the data from some WebServer located in the WebServerDataProvider class. In Order to eliminate the waiting for the webserver i added a DummyDataProvider.
Where would i put such class? I don't like that it is in /src/main/java/my/package/providers/ since it is not real part of the application, but still i need it for development.

Typically you would use such a class in your unit tests. Roboguice works well with Robolectric , which allows you to mock things like http access. If you do that you would put your code in src/test/java/...

You could put it into the main project if you want to use it for fiddling around with the application without bothering the server each time and deactivate it with some constant for deployment, e.g.
if (DEBUG) {
setDataProvider(new MockDataProvider());
}
Proguard should be smart enough to remove this unused class if you remember to reset your variable (you might have to fiddle around with the settings there).

Related

SonarQube demanding tests on conditions for Spring application with mock components

I have a Spring Boot service implementation that communicates with three different external services (APIs and SOAP Web Services). Some times those services can go into maintenance and I needed to implement a mechanism to “bypass” or “mock” them. The approach I am following to achieve this is to include some entries in the properties file:
service1.bypass.enable=true
service2.bypass.enable=true
service3.bypass.enable=true
So inside my code I just need to verify if those properties have value set in true and either use the right implementation or bypass (return a mock).
#Value("service1.bypass.enable")
private boolean service1Bypass;
//Inside the methods
if (!service1Bypass) {
callService();
} else {
callMock();
}
This is causing some troubles at the moment my code is scanned by SonarQube because I need to test when each service is mocked or not which I think is not relevant. Do you know if there’s any workaround or a better way to code this? this project is using Spring and Maven with Java 8
I believe there’s a misconception between “bypassing” and “mocking”.
When you bypass a service, it means you “skip” it, in other words you do not call that service and move forward with your next steps.
When you "mock" a service, your logic is not “skipping” the call to that service, you create a component (that belongs to your code project) that would imitate the behavior of the real service but it will return some “test” or “fake” response.
Mocking is pretty useful technique for testing or for the scenario you describe in which many of the services you are consuming can go into maintenance and impact other people that want to consume your service.
Now, going back to the problem you have, you can solve this in two ways, the first one, if you are using the Jacoco Coverage Plugin, then just add the following tags to your pom.xml file (since I believe you are using maven).
<properties>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPaths>target/jacoco.exec</sonar.jacoco.reportPaths>
<sonar.language>java</sonar.language>
<sonar.exclusions>YOUR PACKAGES GOES HERE</sonar.exclusions>
</properties>
Besides that, I believe your approach is not bad, but it can lead to some issues such:
You are mixing your “mocking” logic inside the business logic which can be a little bit messy.
When analyzing the code with tools such SonarQube (static analysis), you will find that each condition usually demands a test case (which I believe is the problem you have)
You are using now three properties because you connect to three services, but what if you need to consume eight or nine services? Would you add eight or nine properties? I mean, you can, but can be a little messy IMHO.
Since you are already using Spring, I believe that more than a workaround, a good approach to solve the issues would be to take a look to Spring Profiles.
For a more detailed tutorial you can also take a look to: https://www.baeldung.com/spring-profiles
Let’s take an example for your case:
You will only need to define one property instead one for each service in your properties file, this property is called: spring.profiles.active
You can assign one or more values to that property (separated by commas).
For instance:
If you want to mock one of the services, you can go with the following: spring.profiles.active=mockservice1
If you want to mock two (or more) services: spring.profiles.active=mockservice1,mockservice2
Instead of using conditional structures, you will create a class for each service you want to mock and annotate with #Profile(“mockservice1”) or handle through #Configuration or #Bean annotations.
Hope this can help you in some way to fix your issues.

How to intercept and change values

I'm developing in eclipse (java 6) and working with websphere server.
How can I automate a dynamic modification of some small parts of the code (mock-like) for my local development only? I don't want to share my own adjustments with other developers... That could create bad expectations including them thinking it should be working in a certain way that is not correct or even outside communications not happening as they should.
I'm not using any java framework, that is what has been decided for the project.
I have already looked at ASM and BCEL but I can't find any good source on how to get them working in an automated way for this kind of thing... If they are capable of it.
The changes I need can all be achieved by intercepting values of parameters of some specific methods (some are static and other are not static) when they are called.
Anything that can be automated to get that result without changing any of the code shared between the other developers can do. It doesn't need to automatically adapt to new code.
I have already been called to attention of my own adjustments being sent to the repository and I want to avoid it at my best capability.
It’s quite unclear what you are trying to achieve but it sounds like you want local modifications to the code? If so, modify the code, commit the changes to a branch that you never publish. Merge incoming changes into this branch every now and then.

Mocking a resource on Android instrumentation test

I want to test the effects of a library call of my program with a real device. This call starts a service, that sends an HTTP request to a server whose URL that is hard-coded in the resources.
I want to verify that the request is sent correctly. So I set up a local HTTP server, but to be able to use it I have to change/override/mock the resource so it points to http://127.0.0.1 instead.
I want to do "end-to-end" testing; in this case it's important that the service makes an actual network request, although locally.
I've tried to override the value by creating a string resource with the same name in androidTest/res/values/strings.xml, but that resource is only visible in the test package, not in the application package.
Using the Instrumentation class only allows me to obtain the Context reference, but there's no way to replace it (or the return value of getResources()) with a mock or something similar.
How can I change a resource value of an Application under test?
You have a couple choices:
Dependency injection
Stubs/mocks
SharedPreferences
Scripts or gradle tasks
Dependency injection
Use a library like RoboGuice or Dapper. Inject an object that handles making the API requests. Then, in your test setup, you can replace the injection modules with testing versions instead. That way your test code runs instead of the original; that code can pass in different strings (either hard-coded or from the test strings.xml) instead.
DI libraries can be expensive to setup: high learning curve and can be performance problems if not used correctly. Or even can introduce hard to debug problems if the scope/lifetime of the objects isn't configured correctly. If testing is the only reason to use DI, it might not be worth it to you if you're not comfortable with a DI container.
Stubs/mocks
Wrap up your calls in something that implements a custom interface you write. Your main implementation then fills in the host URL and calls the API. Then, in tests, use a combination of stubs or mocks on that interface to replace the code that fills in the host URL part.
This is less of an integration test since the stubs or mocks will be replacing parts of the code. But is simpler than setting up a dependency injection framework.
SharedPreferences
Use the Android SharedPreferences system. Have it default to a certain endpoint (production). But allow the app to be started on the testing device, then some dialog or settings to let you change the host URL. Run the tests again and now they point to a different API URL.
Scripts or gradle tasks
Write some script or gradle task to modify the source before it is compiled in certain scenarios.
This can be fairly complicated and might even be too platform or system-dependent if not done right. Will probably be fairly brittle to changes in the system. Might introduce bugs if the wrong command is run to build the final packaged version and the wrong code goes out to the market.
Personal opinion
Which do I recommend? If you and/or your team is familiar with a DI library like RoboGuice or Dapper, I recommend that option. It is the most formal, type-safe and strict solution. It also maintains more of the integrity of the stack to test the whole solution.
If you're not familiar with a good DI library, stubs/mocks and interface wrappers are a good fall back solution. They partly have to be used in the DI solution anyway, and you can write enough tests around them to cover a good majority of the cases you need to test (and are in control of). It is close enough to the DI solution that I would recommend this to everyone who doesn't use DI in the project already.
The SharedPreferences solution works great for switching between staging and production environments for QA and support. However, I wouldn't recommend it for automated tests since the app will most likely be reinstalled/reset so often during development, it would get annoying resetting that URL that often. Also, first runs of tests would probably fail; headless tests on a CI server would fail, etc. (You could default the URL to the localhost, but then you run the risk of accidentally release that default to production sometime.)
I don't recommend scripts or the hacked-up gradle tasks. Too brittle, less clear to other developers that come behind you, and more complicated then they're worth, IMO.
In addition to Jon Adams's solutions, there's a further one:
Override resource in build type
By default, a library module is built in release mode when it's used by another module. The debug mode is only used for testing (unit tests and instrumented tests). Therefore, using the resource overriding it's possible to change the resource value for the instrumentation tests for that library only, and use the original value in the library's users.
This has some caveats though:
Instrumented/integration tests must stay on the library itself, not on the main application package;
The same resource values have to be shared across all tests (unless using product flavors)

Scala library initialization design

I have started an open source Scala project named omniprop. The feature I'm currently exploring is how to allow users of the project to stack JVM-styled property providers. For instance, you may wish to look up properties in java.lang.System, Lift's util.Prop, and Typesafe's Config library. Due to some other constraints/features of omniprop, I need this stack configuration to reside in a known object, so other parts of the library can retrieve properties from this stack.
In order for omniprop to work correctly, this configuration needs to be invoked by the user of the library before any properties are accessed. Hence any project which uses my library will need a bootstrap/initializer which can set up the provider stack. An example of this initial configuration code looks like this:
import com.joescii.omniprop.providers._
PropertyProviders.configure(List(
SystemPropertyProvider,
LiftPropsProvider
))
The challenge I'm facing is with testing in particular. In order for the test code for a project utilizing omniprop to work, it must somehow run the above code before any tests are run. Currently, I don't see a clean way to do this with sbt or any of the testing libraries I am familiar with such as scalatest, scalacheck, or specs2. As it is, one would need to call the above snippet in every test suite, which is certainly not ideal.
Another approach this this problem is what Lift does, in which every project necessarily has a class called bootstrap.liftweb.Boot that the library invokes to set everything up. I find that to be a reasonable approach to a web framework such as Lift, but seems to be too much for a tiny property helper library.
I really have two questions here:
How can I have sbt invoke the above setup code with the correct classloader before all tests run?
More importantly, is this the best design for a library which requires initialization, or is there a better approach?
Using ScalaTest, when I've had to do something similar, I created a trait that extends BeforeAndAfterAll, which I mixed into every suite that needed it.
trait Configure extends Suite with BeforeAndAfterAll {
override def beforeAll() { PropertyProviders.configure(/*...*/); }
override def afterAll() { PropertyProviders.configure(/*...*/); }
}
You just mix it in like any other trait
trait FooSpec extends Spec with Configure {
// ...
}
You could put the initialization code in a trait constructor and have your tests extend from that trait.
Another approach is to have that configuration as the default, and if no configuration is set then it gets used the first time your library code is called. That would cover both testing and non-testing scenarios.
A hybrid approach would be to have your sbt testing configuration set a system property. If that system property is set and no configuration is has been set then the testing config will be used the first time the library code gets called.

run junit as server and inject changes?

for some testing purposes it would be great not having to restart my jetty server for every test run.
With jrebel i can apply source changes directly.
Is it possible to run my jetty server in a way that i could inject changes dynamically and then rerun the tests without having to restart the server?
It depends on the kind of changes that you want to inject.
That said, I believe there is a deeper issue here. Restarting Jetty is the right thing to do from a test-quality standpoint. It ensures that each test starts from a clean page thereby minimizing the risk of inter-test dependencies. On the other hand, this is costly (time-wise) and make your suite runs slower.
If I were you, I would address this as follows: I will refactor the code that I want to test (presumably: servlets) such that they do not depend on the Jetty infrastructure, and can run stand-alone. For instance, If I have a servlet class SomeServlet with its doGet() method, I will refactor it such that it implement MyServelt whose goGet() takes a MyRequest, MyResponse parameters.
Once you do that, you can unit-test MyServlet without a Jetty server. This will allow you not only to test faster, but also ease your debugging sessions and make your components more decoupled. Of course, you will need to add some plumbing code: a class that adapts the servelt interface to a MyServelt object (via delegation).

Categories