How to unit test Eclipse plugin? - java

I want to improve the Builder Pattern Eclipse Plugin. I want to change the code generated to support generics class and include the class name in the builder class name.
I located where I must add my changes. I want to use TDD but I'm stuck as I don't know how to create an ICompilationUnit type. I want to create an ICompilationUnitfrom test file and then compare the result to what I expect. I know I can mock it but I don't know well the interface and what each method should do.
I didn't find resources to solve my problem. The resources I found are about GUI testing.

Sadly, the ICompilationUnit defined by JDT is not a simple class, so if you want to unit test it, either you have to mock it (and thus understand what is expected), or you have to use JDT to parse it. For basics, you can use the vogella.com JDT tutorial.
Furthermore, I would look into the test suite of JDT itself, as there were similar issues solved already.

Related

Best way of reusing Java classes across different projects?

I am currently writing Selenium WebDriver tests for a variety of websites each using the same proprietary framework.
Because of this, there are many test cases that can be quite similar across different websites. As such I have made my test classes as generic as possible and made it so that every XPath/CSS Selector/ID used to locate elements is defined in a Constants class, which is unique to every project.
But, in some cases, the code for the same test can be the same across different websites, since I wrote them generically.
In addition each test is a direct/indirect extension of a BasicTest class which contains code that is likely to be reused by different tests (ex: WebDriver instance declaration, etc)
The way I thought about setting my test structure was the following:
one generic project that is "reused" by each subsequent project;
one project per website with its own definition of the Constantsclass and a TestSuite class that it can use to run both generic tests and tests specific to itself.
This would allow me not to have copies of these generic tests in each of my test projects.
The problem is that I don't really know how to set this up. The GenericProject is going to contain tests that require variables from Constant, but it makes no sense to have generic Constants. Plus, will I be able to call those tests inside my website project-specific TestSuites? If I redefine Constants in each specific project, will those constants be used for the generic tests defined in GenericProject?
How can I even set it up so that I can reuse Project A's classes inside of Project B, C, D... etc?
Extract your constants to a properties file which exists in each module as src/test/resources/common.properties.
Use org.apache.commons:commons-configuration2 PropertiesConfiguration to read this file. It will handle nested properties just fine.
Common code can be shared by depending on your GenericModule. Official instructions for two models of doing this (extract common tests to a new module or use a test-jar) are here
In general in order to reuse code over projects you would create a library containing the reusable code. In order to do so you'd need to think about a suitable API for the library.
This contains decisions about:
How will functionality be called from dependent code
How will dependent code provide required data.
If you are using constants for e.g. CSS selectors, that are different but have the same semantics, e.g.
root frame
side panel
main area
...
you might want to define an interface that the dependent code can provide. This could look like:
interface CssSelectors {
String rootFrame();
String sidePanel();
//...
}
If you are building this for tests you might also want to use features of your test framework (e.g. Rules in JUnit).
When reusing code in tests you also should consider another aspect:
If s.o. reads the tests written with your library, will she be able to sufficiently understand what is happening behind the border of the library to understand what the test is all about? This is a lot more of a question when dealing with test code than with production code as for test coverage and validity of tests it often matters a lot more how a setup or verification is done than is the case for production code.

How to mock a static call on a class from a third-party library

I am wondering whether it is possible with PowerMock or any other library to mock out a static call in a class from a library. The class in that third-party library makes a call to one of the classes in the rt.jar and I want a return a custom implementation of that returned Type. I am trying to do this outside of test code.
Otherwise, I had to extend a few classes from that library and replace some implementation. Has someone done anything like this before?
Yes it is possible, e.g. using PowerMock.mockStatic() or PowerMock.mockStaticPartial() if you want to mock one method, only.
There is a quite good tutorial on the homepage of PowerMock.
I posted an example on SO.
[EDIT] IF you want to do such magic in production code, however, I would recommend NOT to use a Testing-Framework. Maybe Groovy can help you with that - it is possible with Groovy to manipulate classes (even JDK classes) at runtime, and it is (I think) a thinner layer on top of the JVM.
Generally speaking it's really bad idea to do such hardcore stubbing (it's not mocking what you describe). I'd go with building tiny abstraction over this library so that you can have full control on what you want to return. It is possible to use some features of PowerMock outside tests but this not piece of cake. Here you have rough description that can help if you really want: https://groups.google.com/d/msg/powermock/SMDMe-y6fLg/1HF0TsGOqTIJ
Anyway I would not recommend doing that.

JCodeModel to use in custom maven archetype

I am new to maven and Jcodemodel. I am trying to create an archetype which will accept the wsdl and generate the code. I need to create java code for implementation class file by implementing the interface. I need to use JCodeModel to generate java code. But I am new to JCode. How to use Jcodemodel inside Maven archetype to generate java code?
Kindly, guide me
Maven will build your projects and automate some aspects of managing the builds and the project; but, it will not decide for you what the project does, or how to go about writing the project.
You might need to write Java code that (because you mentioned a WSDL) runs as a web service. That web service apparently should accept "something" and reply back with "something". It is a guess (this is a very vague question), that the something it should accept is some sort of description of a Java class, and the something it should reply will be either Java source code, or a compiled java class.
In either case, the project can be managed by Maven, meaning that Maven will compile, test, and package your project. In certain cases, it will also deploy it (if you configured Maven to do so).
Now if you want Maven to actually accept the WSDL and generate the code, then what Maven will build will be static, meaning that the "generated" code will not be able to change after Maven completes the build. You can; however, build the "next" version which might change. If this scenario sounds more like what you had in mind, then your "source" would be a static file, and the "built project" would be the source code or the object code corresponding to the source.
Without more direction, this is probably the best guide you are going to get. It is just too vague a question, covering too much ground to say much definitively. You also seem to lack a lot of knowledge in a lot key places simultaneously; perhaps the best solution is to identify what you will likely need to brush up on, order those by "what needs what" and start with the element that depends on nothing else.

Use Javassist in JUnit test

I have quite shallow understanding of JUnit and Javassist, i just want to use them to do some program analysis. For example given a library, I want to know during the runtime what methods in the library have been invoked. I can use bytecode manipulation to insert a system.out.println("method_name"); statement in the beginning of a method. So during the runtime, it will print out what methods have been invoked.
In standalone application i can intercept before the main() is called and use my own class loader(see below), however in JUnit there is no main(), could anyone show me how to intercept at this situation?
Many thanks.
...
Loader loader = new Loader( pool );
loader.addTranslator( pool, xlat );
loader.run( className, args );
...
Edit: I use JUnit 4.8 and Javassist 3.15.0.GA
Might I recommend an alternative approach instead? You can use an aspect-oriented approach instead, using AspectJ. With that, you can define pointcuts around a subset of or all methods that you want to monitor.
Another option is, if you're looking to monitor code coverage (the fact that you're using JUnit and just looking to do System.out.println(...) are good hints of this), maybe you're looking for a code coverage tool? If so, Cobertura would be your best bet - with no custom coding required.
Both of these options do their own byte-code manipulation, but without being something that needs to be maintained by the developer.
If you're using Eclipse as your IDE, both of these tie-in very nicely to Eclipse. AspectJ is actually an Eclipse project, but doesn't require Eclipse. The Eclipse plug-in for Cobertura is eCobertura.
Yet another option for this is to do it within JUnit itself - and this wouldn't require any bytecode manipulation. Take a look at its TestWatchman class. I don't yet have this documented online as I do with my other libraries, but you could take a look at my BaseTest class as part of my JUnit utilities library. Any JUnit test class that extends this will automatically log (to SLF4J) when each test starts, succeeds, or fails. However, this is all at a test-level only, and won't help monitor other methods that each test runs.

Creating nunit tests without exporting them with the api

I'm new to unit testing using nunit (and Java development in general). When creating unit tests for private methods on classes, it looks as though the test file must be in the same package as the class being tested. What is the typical way of avoiding exporting the APIs of the unit tests? Can I make the classes/test methods package-protected? Or do developers typically have a separate build for release that excludes unit test files?
I can tell IntelliJ or Ant not to package JUnit tests in the deployment. I have tests in a separate directory from the source code, which is what makes it possible.
Don't mingle source and test classes together. Keep them separate to make it easier for the tool/script you use to deploy.
The test file does not necessarily have to be in the same package as the class being tested. In fact, it is a good practice to have the test files in a completely separate package, allowing them to test the public API without being concerned with package-level implementation details.
Alternately, you can set up your build script (e.g. Nant) to ignore files containing "Test" when you build your release executable.
Personally my approach is only to test exposed functionality, so you end up testing well encapsulated parts only.
This usually leads my design to contain small classes with well defined functionality, which are easier to test.
Generally, when unit testing you shouldn't be concerned with the internals of what you're testing, so I find this is the best way to approach it.
I also agree it's best to seperate test and production code.
Keep test source code out of application source code. In general, only test exposed functionality. If you really need to test private behavior, create a test object that extends the real object and allows publec access to the private behavior.
I think it's a mistake to move your test code out of the package of the CUT (Class Under Test). At some point you may want to test a protected method or class, and having your test code in another package makes that hard or impossible.
A better solution is to create a separate directory for your test code that simply mirrors the package structure of your production code. Here's what I do:
src/main/java/com/example/Foo.java
src/test/java/com/example/FooTest.java
Then your build script can very simply ignore src/test/** when it comes time for packaging and deployment.

Categories

Resources