Use different structure for grails unit tests - testing

I have a very simple package structure, only one level deep for all my grails artifacts- the name of the application "estra"- because the grails application structure is already providing the separation folders. But when writing unit-tests all the classes are inside the same estra.* package and I want to keep them separated like this estra.domain, estra.controllers, etc.
Right now everything works fine, but the tests are pretty simple. Will I face any problem in the future with dependency injection or something?

No, the package name don't influence in your test since in your test class you "say" which class is tested, using the #TestFor annotation. But remember that in unit tests you need to manually set your dependencies.
class ServiceOne {
def serviceTwo
}
#TestFor(ServiceOne)
class ServiceOneTests {
#Before
public void setup() {
service.serviceTwo = new ServiceTwo() //or mocked instance...
}
}

Related

Run Spock tests under common spring context

I use Spock framework to run my tests. Each test class has Spring's annotation #ContextConfiguration over it. As I see context is brought up for every test class and it takes a lot of time to run a couple of dozens of tests in different classes. Is there a way to configure Spock test classes to run under common spring context?
It's not about spock but about spring.
Spring can cache in general application context across many test cases but you have to know how to do it right.
As a first resort, make sure, that 'locations' attribute of #ContextConfiguration is the same.
In addition, it's possible to take advantage of #ContextHierarchy annotation.
This caching facility is quite fragile, but works.
Maybe it makes sense to create a common specification with all the annotation and inherit from it:
#ContextConfiguration(locations = ...)
// or maybe
#ContextHierarchy (...)
public abstract class MyCommonSpec extends Specification {
}
// and not in tests:
public class MyTest1 extends MyCommonSpec {
...
}
public class MyTest2 extends MyCommonSpec {
...
}
Here is a link on a very relevant discussion
Possible approach that will work: create multiple classes with tests. For example, A, B, C, D. Make inheritance like: D -> C -> B -> A. Run tests in D, this will execute all the tests from A,B,C,D under common spring context.
I assume that this approach is not so neat and perfect, but it solves initial problem.

Is it bad idea to use Dependency Injection objects in unit tests?

I am not sure if what i am doing is actually the "correct" way of doing unit tests with DI. Right now i ask my ViewModelLocator to actually create all the instances i need, and just get the instance i need to test, which makes it very simple to test a single instance because lets asume that Receipt needs a Reseller object to be created, reseller needs a User object to be created, user need some other object to be created, which creates a chain of objects to create just to test one single instance.
With di usally interfaces will get mocked and parsed to the object which you would like to create, but how about simple Entities/ViewModels?
Whats the best practice to do unit testing with DI involved?
public class JournalTest
{
private ReceiptViewModel receipt;
private ViewModelLocator locator;
[SetUp]
public void SetUp()
{
locator = new ViewModelLocator();
receipt = SimpleIoc.Default.GetInstance<ReceiptViewModel>();
}
[TearDown]
[Test]
public void CheckAndCreateNewJournal_Should_Always_Create_New_Journal()
{
receipt.Sale.Journal = null;
receipt.Sale.CheckAndCreateNewJournal();
Assert.NotNull(receipt.Sale.Journal);
}
}
First, you aren't using Dependency Injection in your code. What you have there is called Service Locator (Service Locators create a tight coupling to the IoC/Service Locator and makes it hard to test).
And yes, it's bad (both Service Locator and Dependency Injection), because it means: You are not doing a UnitTest, you are doing an integration Test.
In your case the ReceiptViewModel will not be tested alone, but your test also tests the dependencies of ReceiptViewModel (i.e. Repository, Services injected etc.). This is called an integration test.
A UnitTest has to test only the class in question and no dependencies. You can achieve this either by stubs (dummy implementation of your dependencies, assuming you have used interfaces as dependencies) or using mocks (with a Mock framework like Moq).
Which is easier/better as you don't have to implement the whole class, but just have to setup mocks for the methods you know that will be required for your test case.
As an additional note, entities you'll got to create yourself. Depending on your UnitTest framework, there may be data driven tests (via Attributes on the test method) or you just create them in code, or if you have models/entities used in many classes, create a helper method for it.
View Models shouldn't be injected into constructor (at least avoided), as it couples them tightly
Units tests should run quickly and should be deterministic. That means you have to mock/stub everything that brokes these two rules.
The best way to mock/stub dependancies is to inject them. In the production, classes are assembled by DI framework, but in unit tests you should assemble them manually and inject mocks where needed.
There is also a classic unit test approach where you stub/mock every dependency of your class, but it's useless since you don't gain anything by that.
Martin Fowler wrote great article about that: link
You should also read Growing Object-oriented software: Guided by tests. Ton of useful knowledge.

Why doesn't HttpClient tear down properly between unit tests in grails

I have two Controller unit tests and each one sets an HttpClient metaclass execute in setUp() like the following:
HttpClient.metaClass.execute = { HttpUriRequest request ->
<return expected data for my tests>
}
Then I attempt to tear down the metaClass in tearDown() with the following code:
protected void tearDown() {
super.tearDown()
GroovySystem.metaClassRegistry.removeMetaClass(HttpClient.class)
}
However only one of my unit tests passes because the return from the HttpClient is incorrect/unexpected. If I add the logic needed for both tests in the metaClass.execute of both tests I get no testing failures. However this is cumbersome and impractical, especially in an agile development environment.
What am I doing wrong with trying to tear down this HttpClient metaclass registration? How can I troubleshoot this further?
I'm currently using grails 1.3.7 on a CentOS 5 install.
Edit: I should clarify that my problem is that the metaClass override is causing issues between test classes, not test cases. We've been setting up the metaClass override so that it will return correct data for all of the test cases in a given class. So Test class A has the metaClass data for it's test cases and Test class B has the metaClass data for it's test cases. The issue is that since Test class A gets tested first, test class B ends up using the metaClass definition from test class A and fails because of this.
You shouldn't need to implement a tearDown method. Assuming you're extending ControllerUnitTestCase or GrailsUnitTestCase If you call registerMetaClass HttpClient before you metaClass the execute method it will replace the metaClass for HttpClient in between test classes for you. I've never used the removeMetaClass method so I don't know why that wouldn't be working so I can't answer the question of why that doesn't work, but this should get you past your issue.
...
registerMetaClass HttpClient
HttpClient.metaClass.execute = { HttpUriRequest request ->
<return expected data for my tests>
}
The solution I ended up using is a bit of a hack but it's easier to maintain. I just made a class in src/groovy that creates the HttpClient.metaClass and then just made each test class that needs it run the static method on the new class. That way all of the necessary code for the meta classing is in one place.

How to manage IoC containers in tests?

I'm very new to testing and IoC containers and have two projects:
MySite.Website (MVC)
MySite.WebsiteTest
Currently I have an IoC container in my website. Should I recreate another IoC container for my test? Or is there a way to use the IoC in both?
When you have an IoC container, hopefully you will also have some sort of dependency injection going on - whether through constructor or setter injection.
The point of a unit test is to test components in isolation and doing DI goes a long way in aiding that. What you want to do is unit test each class by manually constructing it and passing it the required dependencies, not rely on container to construct it.
The point of doing that is simple. You want to isolate the SUT(System Under Test) as much as possible. If your SUT relies on another class and IoC to inject it, you are really testing three systems, not one.
Take the following example:
public class ApiController : ControllerBase {
IRequestParser m_Parser;
public ApiController(IRequestParser parser) {
m_Parser = parser;
}
public ActionResult Posts(string request) {
var postId = m_Parser.GetPostId(request);
}
}
The ApiController constructor is a dependency constructor and will get invoked by IoC container at runtime. During test, however, you want to mock IRequestParser interface and construct the controller manually.
[Test]
public void PostsShouldCallGetPostId() {
//use nmock for mocking
var requestParser = m_Mocks.NewMock<IRequestParser>();
//Set up an expectation that Posts action calls GetPostId on IRequestParser
Expect.Once.On(requestParser).Method("GetPostId").With("posts/12").Will(Return.Value(0));
var controller = new ApiController(requestParser);
controller.Posts("posts/12");
}
Testing is about real implementation. So you normally should not use IOC in your unit tests. In case you really feel needing it (one component depending on another one), using an interface to isolate the interaction and using a mocking lib (Moq is good) to mock it and do the testing.
The only chance I see IOC container is necessary for testing is in integration testing.

How can I avoid global state?

So, I was reading the Google testing blog, and it says that global state is bad and makes it hard to write tests. I believe it--my code is difficult to test right now. So how do I avoid global state?
The biggest things I use global state (as I understand it) for is managing key pieces of information between our development, acceptance, and production environments. For example, I have a static class named "Globals" with a static member called "DBConnectionString." When the application loads, it determines which connection string to load, and populates Globals.DBConnectionString. I load file paths, server names, and other information in the Globals class.
Some of my functions rely on the global variables. So, when I test my functions, I have to remember to set certain globals first or else the tests will fail. I'd like to avoid this.
Is there a good way to manage state information? (Or am I understanding global state incorrectly?)
Dependency injection is what you're looking for. Rather than have those functions go out and look for their dependencies, inject the dependencies into the functions. That is, when you call the functions pass the data they want to them. That way it's easy to put a testing framework around a class because you can simply inject mock objects where appropriate.
It's hard to avoid some global state, but the best way to do this is to use factory classes at the highest level of your application, and everything below that very top level is based on dependency injection.
Two main benefits: one, testing is a heck of a lot easier, and two, your application is much more loosely coupled. You rely on being able to program against the interface of a class rather than its implementation.
Keep in mind if your tests involve actual resources such as databases or filesystems then what you are doing are integration tests rather than unit tests. Integration tests require some preliminary setup whereas unit tests should be able to run independently.
You could look into the use of a dependency injection framework such as Castle Windsor but for simple cases you may be able to take a middle of the road approach such as:
public interface ISettingsProvider
{
string ConnectionString { get; }
}
public class TestSettings : ISettingsProvider
{
public string ConnectionString { get { return "testdatabase"; } };
}
public class DataStuff
{
private ISettingsProvider settings;
public DataStuff(ISettingsProvider settings)
{
this.settings = settings;
}
public void DoSomething()
{
// use settings.ConnectionString
}
}
In reality you would most likely read from config files in your implementation. If you're up for it, a full blown DI framework with swappable configurations is the way to go but I think this is at least better than using Globals.ConnectionString.
Great first question.
The short answer: make sure your application is a function from ALL its inputs (including implicit ones) to its outputs.
The problem you're describing doesn't seem like global state. At least not mutable state. Rather, what you're describing seems like what is often referred to as "The Configuration Problem", and it has a number of solutions. If you're using Java, you may want to look into light-weight injection frameworks like Guice. In Scala, this is usually solved with implicits. In some languages, you will be able to load another program to configure your program at runtime. This is how we used to configure servers written in Smalltalk, and I use a window manager written in Haskell called Xmonad whose configuration file is just another Haskell program.
An example of dependency injection in an MVC setting, here goes:
index.php
$container = new Container();
include_file('container.php');
container.php
container.add("database.driver", "mysql");
container.add("database.name","app");
...
$container.add(new Database($container->get('database.driver', "database.name")), 'database');
$container.add(new Dao($container->get('database')), 'dao');
$container.add(new Service($container->get('dao')));
$container.add(new Controller($container->get('service')), 'controller');
$container.add(new FrontController(),'frontController');
index.php continues here:
$frontController = $container->get('frontController');
$controllerClass = $frontController->getController($_SERVER['request_uri']);
$controllerAction = $frontController->getAction($_SERVER['request_uri']);
$controller = $container->get('controller');
$controller->$action();
And there you have it, the controller depends on a service layer object which depends on
a dao(data access object) object which depends on a database object with depends on the
database driver, name etc