I am having problems integration testing my Grails service because the service under test is not being injected in to my test. I have followed the advice from answers to questions else where on Stackoverflow but as yet can not get my service injected. The following class is under /<project_root>/test/integration/com/example:
package com.example
import grails.test.GrailsUnitTestCase
class MyServiceIntegrationTest extends GroovyTestCase {
MyService service;
public void testService() {
assert service != null
}
}
I have tried executing both from the command-line (grails test-app) and from within IDEA both result in the same failure, namely service is null
This is Grails 1.3.6
Any suggestions on how to get my integration test working please?
Autowiring works the same way in integration tests as in other parts of the framework, so you need to make sure the property is named like the service except with the appropriate unCamelCase.
class MyServiceIntegrationTest extends GroovyTestCase {
def myService
}
Assuming your service is an object named MyService.
Related
In my current setup i want to unit test a Grails service that has an #autowired dependency and inject a mock for the dependency.
class AcmeService {
#Autowired
FooService fooService // not a Grails service!
}
The FooService is not a Grails service but it is a dynamic implementation from a FeignClient. I am looking for a way to inject a Mock for the FooService service in a UnitTest. What would be the best solution to do this?
I tried setting the dependency in the setup, but then i get a 'Unsatisfied dependency expressed through field fooService'
class AcmeService extends Specification {
FooService mockedFooService = Mock(FooService)
def setup() {
service.fooService = mockedFooService
}
}
you can add the following to your unit test:
def doWithSpring = {
fooService( InstanceFactoryBean, Mock(FooService) )
}
I have a Sample Grails Service and trying to auto wire it inside integration test of Grails. All though the IntelliJ editor shows its auto-wired, but at runtime I always get it as null.
Integration Test is as below where I sampleService as always null.
class Sample {
def sampleService;
#Test
public void testSample() {
println(" Hello...")
}
}
After adding #Autowired explicitly to my service resolved the issue. Refer the code below
class Sample {
#Autowired
def sampleService;
#Test
public void testSample(){
println(" Hello...")
}
}
I am using NServiceBus is an azure worker role via convention by having configuration in app.config and azure Queue details in .csdef.
I have a rest service that accesses the IBus by doing this:
Configure.Instance.Builder.Build<IBus>()
and works fine!
I have a class that implements IWantToRunAtStartup where I do the configure bootstrapper as follows:
Bootstrapper.With.StructureMap()
.UsingAutoRegistration()
.And.AutoMapper().Start();
I'm losing the IBus reference if I then use the bootstrap container:
Configure.Instance.StructureMapBuilder((IContainer) Bootstrapper.Container);
How do I use Bootsrtrapper.StructureMap and NServiceBus?
Telling us which container you want to use needs to be done from a IConfigureThisEndpoint and IWantCustomInitialization class, example:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
Configure.With()
.StructureMapBuilder((IContainer) Bootstrapper.Container);
}
}
I have a very simple Grails Service:
class UserService {
def returnHi() { return "Hi" }
}
I'm trying to get access to the service in an integration test, like this:
def testService() {
UserService userService
assertEquals( "Hi", userService.returnHi() )
}
Why do I get the failure:
java.lang.NullPointerException: Cannot invoke method returnHi() on null object?
Thanks for your time
It's enough to put 'def userService' as your class field instead of putting in inside of the method. In integration tests, beans are injected the same as in controllers, services and other beans.
Do something like:
class MyTests {
def userService
void serviceTest(){
assert userService.returnHi(), 'Hi'
}
}
P.S. Make sure the name of the service is correct and written in camelCase.
Add the following lines to the integration test file:
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
def userService = AH.application.mainContext.userService
as described here: Service is not getting injected into Grails domain class , Grails 2.0.0 and 2.0.3
I am using Log4Net as a service which is injected into other services using StructureMap.
How do I ensure the log file includes the calling service class context (class name and/or thread) which is making the log4net calls?
Surely the calling class or thread will always be the logging service which doesn't help me understand where the logging calls are really coming from.
EDIT:
Register code:
ObjectFactory.Initialize(x =>
{
x.For<ILog>().AlwaysUnique().Use(s => s.ParentType == null ?
LogManager.GetLogger(s.BuildStack.Current.ConcreteType) :
LogManager.GetLogger(s.ParentType));
});
Service layer:
public class LoggerService : ILoggerService
{
private readonly ILog log;
public LoggerService(ILog logger)
{
log = logger;
log.Info("Logger started {0}".With(logger.Logger.Name));
}
public void Info(string message)
{
log.Info(message);
}
}
In the logging, I am still always getting the LoggerService as the context so I'll never see what actually called the logger. It doesn't seem to be working correctly. I feel like I'm missing something here...
Edit 2:
I've added a pastie link for a console app here:
http://pastie.org/1897389
I would expect the parent class to be logged but it isn't working at the simplest of levels.
You might want to have a look at Castle Dynamic proxy in order to solve it using AOP. There is an example of using it with Structure Map on the Structure Map Google Group.
Ayende has an example of AOP based logging using Log4Net and Windsor.
I use StructureMap in a lot of the code I generate and I have a StructureMap registry which I use to hook the logger into the context of the class that it is injected into.
For Reference, I'm using the 2.6.2 version of StructureMap but should be fine with 2.5+ where the new .For<>().Use<>() format is utilized.
public class CommonsRegistry : Registry
{
public CommonsRegistry()
{
For<ILogger>().AlwaysUnique().Use(s => s.ParentType == null ? new Log4NetLogger(s.BuildStack.Current.ConcreteType) : new Log4NetLogger(s.ParentType.UnderlyingSystemType.Name));
XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), "Log.config")));
}
}
What this registry is doing is for anywhere the ILogger is injected, use the class that it's injected into is where the logging messages are logged to/context of.
*Also, in the second line (XmlConfigurator.ConfigureAndWatch) is where I tell Log4Net to get the logging information from the file "Log.config" instead of the application configuration file, you may or may not like that and can be omitted.
The code I use is a common IOC.Startup routine where I would pass if I would like to use the default registery.
ObjectFactory.Initialize(x =>
{
x.AddRegistry<CommonsRegistry>();
...
}
This gives me the calling class name in the logging instance where messages are logged to automatically and all that is required is to inject the logger into the class.
class foo
{
private readonly ILogger _log;
public foo(ILogger log)
{
_log = log;
}
}
Now the messages are logged as context/class "foo".