Disable NancyFx module discovery - unit-testing

Is there a way to disable the module discovery and explicitly specify what module classes to use?
This is for test performance reasons. The project states that:
"[scanning] it is part of the startup of any Nancy application and is only performed once and the information is then cached."
and that's dandy, but it seems every unit test also does this global scan, and then it's not fast enough.

That information is for application runtime, not testing. When you are testing a Nancy application, using our testing features such as the Browser class Nancy will require you to be explicit about this
You do this by using a combination of the Module(...), Module<T>() or Modules(...) methods during the Browser / ConfigurableBootstrapper setup
The one time that the testing features would use all modules during testing is if you've explicitly called AllDiscoveredModules instead

Related

mocking a class used by a Gradle plugin when testing

I'm writing a Gradle plugin that interacts with an external HTTP API. This interaction is handled by a single class (let's call it ApiClient). I'm writing some high-level tests that use Gradle TestKit to simulate an entire build that uses the plugin, but I obviously don't want them to actually hit the API. Instead, I'd like to mock ApiClient and check that its methods have been called with the appropriate arguments, but I'm not sure how to actually inject the mocked version into the plugin. The plugin is instantiated somewhere deep within Gradle, and gets applied to the project being executed using its void apply(Project project) method, so there doesn't appear to be a way to inject a MockApiClient object.
Perhaps one way is to manually instantiate a Project, apply() the plugin to it (at which point, I can inject the mocked object because I have control over plugin instantiation), and then programmatically execute a task on the project, but how can I do that? I've read the Gradle API documentation and haven't seen an obvious way.
A worst-case solution will be to pass in a debug flag through the plugin extension configuration, which the plugin will then use to determine whether it should use the real ApiClient or a mock (which would print some easily grep-able messages to the STDOUT). This isn't ideal, though, since it's more fuzzy than checking the arguments actually passed to the ApiClient methods.
Perhaps you could split your plugin into a few different plugins
my-plugin-common - All the common stuff
my-plugin-real-services - Adds the "real" services to the model (eg RealApiClient)
my-plugin-mock-services - Adds "mock" services to the model (eg MockApiClient)
my-plugin - Applies my-plugin-real-services and my-plugin-common
my-plugin-mock - Applies my-plugin-mock-services and my-plugin-common
In the real world, people will only ever apply: 'my-plugin'
For testing you could apply: 'my-plugin-mock'

JMockit + Jetty in functional tests

I'm using ShrinkWrap to start Jetty server in my integration tests.
Problem:
When I start my test jetty-server and than make mockup of my controller - mockup doesn't work!
I suggest that the reason is different classloaders: JMockit - AppClassLoader, Jetty - WebAppClassLoader.
Question:
How to make mocking works fine?
P.S.
I've googled that -javaagent:jmockit.jar option may help. But it doesn't. Is it necessary for maven project based on 1.7 jdk?
ADDITION:
I've written demo to illustrate my problem. You can find it by the reference.
About my demo:
Except of ten stokes of code, it is identical to those project.
I've only added JMockit and a single mock to illustrate the problem.
You should see JettyDeploymentIntegrationUnitTestCase.requestWebapp method: in those method we make mock which doesn't work.
You can check that Jetty & JMockit loads classes by siblings classloaders, so JMockit simply doesn't see Jetty's classes
URLClassLoader
|
|-Launcher$AppClassLoader
|-WebAppClassLoader
The JUnit test in the example project is attempting to mock the ForwardingServlet class. But, in this scenario with an embedded Jetty web server, there are actually two instances of this class, both loaded in the same JVM but through different classloaders.
The first instance of the class is loaded by the regular classloader, through which classes are loaded from the thread that starts the JUnit test runner (AppClassLoader). So, when ForwardingServlet appears in test code, it is the one defined in this classloader. This is the class given to JMockit to mock, which is exactly what happens.
But then, a copy of ForwardingServlet is loaded inside the deployed web app (from the ".class" file in the file system, so not affected by the mocking as applied by JMockit, which is in-memory only), using Jetty's WebAppClassLoader. This class is never seen by JMockit.
There are two possible solutions to this issue:
Somehow get the class object loaded by WebAppClassLoader and then mock it by calling the MockUp(Class) constructor.
Configure the Jetty server so that it does not use a custom classloader for the classes in the web app.
The second solution is the easiest, and can be done simply by adding the following call on the ContextHandler object created from the WebArchive object, before setting the handler into the Jetty Server object:
handler.setClassLoader(ClassLoader.getSystemClassLoader());
I tested this and it worked as expected, with the #Mock doGet(...) method getting executed instead of the real one in ForwardingServlet.

unit test a servlet with an embedded Jetty

How can we unit test a servlet with an embedded Jetty server?
For example, how to test the servlet method below?
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//any logic inside
}
I vastly prefer testing servlets with an embedded instance of jetty using something like junit to bootstrap it.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/examples/embedded/src/main/java/org/eclipse/jetty/embedded/MinimalServlets.java
that is the minimal example of how to do it.
This is also how we test the vast majority of jetty itself, starting it up and running it through its paces.
For a specific servlet or handler we often use the jetty-client or a SimpleRequest in our jetty-test-helper artifact. A URLConnection works as well.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.toolchain.git/tree/jetty-test-helper/src/main/java/org/eclipse/jetty/toolchain/test/SimpleRequest.java
Here is a test in the jetty-client, it is for jetty-9 so if you want 7 or 8 then look under the corresponding tag, it was refactored quite a bit in jetty-9.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
Note: I recommend you pass 0 as the port for jetty to start up with and that will give you an random open port which you can then pull out of jetty for testing purposes, this avoids the situation where multiple builds are running on CI or parallel builds where there might be a port conflict.
You don't need Jetty to test the servlet, you need a unit testing framework, such as JUnit, Mockito, JMock, etc.
Generally speaking, you don't want to use a servlet container when you do unit testing because you want to focus your test on the actual method being tested, having jetty in the way means that you're also testing jetty behavior. After you've done all your unit tests you can move on to integration tests and system tests, and that part can involve external systems such as jetty (using automation frameworks such as Selenium.)
I use Mockito and PowerMock to do my unit testing, you can check out this code for a working example of a real online service (which you can find here).
I wrote a tutorial about this service and what it contains, this can be found here.
[Added after getting downvotes from time to time on this answer]: And at the risk of getting even more downvotes, all you downvoters need to read the definition of UNIT TESTING before you click the -1 button. You just don't know what you're talking about.

Inconsistent unit tests - failing in test suite, passing separated

I have a unit tests for Zend Framework controllers extending Zend_Test_PHPUnit_ControllerTestCase.
The tests are dispatching an action, which forwards to another action, like this:
// AdminControllerTest.php
public testAdminAction()
$this->dispath('/admin/index/index');
// forwards to login page
$this->assertModule('user');
$this->assertController('profile');
$this->assertController('login');
$this->assertResponseCode(401);
}
// NewsControllerTest.php
public testIndexAction()
{
$this->dispatch('/news/index/index');
$this->assertModule('news');
$this->assertController('index');
$this->assertController('index');
$this->assertResponseCode(200);
}
Both of the tests are passing when they are run as a seperate tests.
When I run them in the same test suite, the second one fails.
Instead dispatching /news/index/index the previous request is dispatched (user module).
How to trace this bug? Looks like I have some global state somewhere in the application, but I'm unable do debug this. How can I dump the objects between the tests in the suite? setUpBefore/AfterClass are static, so there are no so many data about the object instances.
I know this is a kind of guess what question. It's hard to provide reliable data here, because they would took to much place, so feel free to ask for details.
The whole unit test setup is more or less like described in: Testing Zend Framework MVC Applications - phly, boy, phly or Testing Zend Framework Controllers « Federico Cargnelutti.
Solution:
I've determined the issue (after a little nap). The problem was not in unit test setup, but in the tested code.
I use different ACL objects based on module name. Which one to use was determined by static call to action helper, which cached the result in a private static variable to speed things up. This cache was executed only when run in a test suite. I just need more unit tests for this code :)
(I'm sorry for such a rubbish post, but I've stuck with this for a day and I hoped someone else experienced similar kind of this Heisenbug with unit tests in general)
You may try clearingrequest and response objects before dispatching each action, like this:
$this->resetRequest()
->resetResponse()
->dispatch('/news/index/index');

Should I write unit tests as console apps first?

I'm debugging a set of WCF services. Initially, I created some unit tests, but since I'm using threading I often receive "Aborted" or "Stopped" tests without any clear explanation why (this is a known bug in Visual Studio).
I found it extremely challenging to debug the services when I can't even read the log output, so I quickly wrote a custom Assert class and converted all unit tests to console applications. This way, I was able to fix a huge number of simple problems immediately that were hard to impossible before.
So I'm wondering if it is a good idea to write unit tests as (fully automated) console apps first and convert them to real (executes when launching unit tests in VS) tests later.
if you want to stick to the stand alone console app you can have a one fits all aproach: Change
the application type of the MsUnitTest (or NUnitTest) to "Console application"
add a public static void Main() that call your unittests you are interested in.
This exe is can run on its own or it runs in the unittest-ide.
I prefer a standalone consolerunner as described in how-do-i-use-mstest-without-visual-studio