I know that you can simply inject a service in unit test method using:
defineBeans {
someService(SomeService)
}
But when I need to inject service inside a service (the service someService calls itself another service some2Service). When I run the test with above code I receive:
Message: Cannot invoke method someMethod() on null object
Is it possible to inject a service into a service in the unit test?
Thanks. ;-)
To use spring beans in a unit test you need to do the following:
Include all the services and other beans the test depends on in the defineBeans closure.
Set the autowire property to true for beans that need to have other beans injected.
For example:
defineBeans {
someService(SomeService) { bean ->
bean.autowire = true
}
some2Service(Some2Service)
}
you can set your member variable which is service by using ref
MyService(MyProvider) {
userDetailsService = ref("userDetailsService")
springSecurityService = ref("springSecurityService")
userService = ref("userService")
}
Hope that helps
Related
I'm new to AWS server less programming. I've created a sample app. Blog(sample available with Visual Studio) using [.Net Core 1.0], now I want to deploy it locally and test it. I've tried AWS SAM Local and LocalStack but I'm confused as there is no clear explanation or steps for .Net Core application.
Can anyone provide me clear steps to deploy and execute this application locally?
The serverless sample out of the box from Amazon doesn't come with simple "press F5" way to run the code locally.
The easiest way to test your code locally is to create the sample with Unit Tests. These unit tests include everything you need to initialise Functions class so that you can run it. You could move this code into a simple console app or create unit tests that cover all the scenarios you want to test locally.
Here is the sample Unit Test from the project:
public class FunctionTest : IDisposable
{
string TableName { get; }
IAmazonDynamoDB DDBClient { get; }
public FunctionTest()
{
this.TableName = "AWSServerless2-Blogs-" + DateTime.Now.Ticks;
this.DDBClient = new AmazonDynamoDBClient(RegionEndpoint.USWest2);
SetupTableAsync().Wait();
}
[Fact]
public async Task BlogTestAsync()
{
TestLambdaContext context;
APIGatewayProxyRequest request;
APIGatewayProxyResponse response;
Functions functions = new Functions(this.DDBClient, this.TableName);
// Add a new blog post
Blog myBlog = new Blog();
myBlog.Name = "The awesome post";
myBlog.Content = "Content for the awesome blog";
request = new APIGatewayProxyRequest
{
Body = JsonConvert.SerializeObject(myBlog)
};
context = new TestLambdaContext();
response = await functions.AddBlogAsync(request, context);
Assert.Equal(200, response.StatusCode);
My spring boot web application uses Cassandra DB via the Datastax client and the connection occurs as follow:
public CassandraManager(#Autowired CassandraConfig cassandraConfig) {
config = cassandraConfig;
cluster = Cluster.builder()
.addContactPoint(config.getHost())
.build();
session = cluster.connect(config.getKeyspace());
}
When I run my Unit Tests, the spring boot application tries to load the CassandraManager Bean and connect to the Cassandra DB which is not up for the Unit Test as I do not need it. I get the following error: [localhost/127.0.0.1:9042] Cannot connect)
Is there a way to avoid loading this Cassandra Manager Bean to run my UT as they do not need to connect to the DB ? Is it a good practice to do so ?
You can try something like below which worked for me assuming, you are using spring-data-cassandra
First we create another configuration class which will be used for the tests that does not need cassandra connection. It is required as we need to exlude the CassandraDataAutoConfiguration class. Ex:
#SpringBootApplication(exclude = {CassandraDataAutoConfiguration.class})
public class NoCassandraConfig {
}
Then we will use this configuration on our test(s). Ex:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = NoCassandraConfig.class)
public class UtilitiesTest {
/* Lots of tests that does not need DB connection */
}
And there you go.
BusinessLogic project -> having is using to Microsoft.Azure.Documents.Client
In my unit test i have created a mock of
var documentClient = new Mock<IDocumentClient>();
documentClient.Setup(x => x.ReadDatabaseAsync(It.IsAny<Uri>(), null)).Throws(CreateDocumentClientExceptionForTesting(new Error(), HttpStatusCode.NotFound));
now i have to inject documentClient in to BusinessLogic from unit test projects, any ideas on how this has to done ?
I am using spock for may application testing and using Grails 2.4.4. I have done domain, controller, and service unit testing. But in controller sections I am stuck with the role wise access. For authentication I am using Spring Security Core Plugin. Below is my sample code.
#Secured(["IS_AUTHENTICATED_FULLY"])
def index(Integer max) {
}
#Secured(["ROLE_A","ROLE_B"])
def create() {
respond new DomainName(params)
}
#Transactional
#Secured(["ROLE_A","ROLE_B"])
def save(DomainName DomainNameInstance) {
}
How do I test that only the user with ROLE_A and ROLE_B can create and save and other cannot? Also I do I check the user is IS_AUTHENTICATED_FULLY to access index action ?
From your question, it sounds like you are trying to test whether the Spring Security code is working. My take on unit testing controllers is that 'if I didn't write I'm not testing it.' Services used by my controllers are mocked, configuration values used by my controller are mocked. Likewise, Spring Security behaviors are mocked (in effect). This means accepting some amount of risk related to the plugins that you use in your application. Do you trust Spring Security to handle roles and authorities correctly? I generally do.
I'm more interested in the behaviors of my code, so I generally just bypass the spring check in my Unit tests. If you want to verify the behaviors of your application if the user is or is not logged in, or does or does not have a certain role, you can do that.
def "test create method without required role"() {
setup:
// tell Spring to behave as if the user does not have the desired role(s)
SpringSecurityUtils.metaClass.static.ifAllGranted = { String role ->
return false
}
when:
controller.index()
then:
// without the required role, what does the controller return?
controller.response.status == ??
cleanup:
SpringSecurityUtils.metaClass = null
}
def "test create method with required role"() {
setup:
// tell Spring to behave as if the user has the required role(s)
SpringSecurityUtils.metaClass.static.ifAllGranted = { String role ->
return true
}
when:
controller.index()
then:
// with the required role(s), what does the controller return?
controller.response.status == 200
controller.response.mimeType.name == "application/json"
controller.response.getText() == "whatever"
cleanup:
SpringSecurityUtils.metaClass = null
}
I'm trying to figure out how to access Spring beans from a subclass of JerseyTest.
Extending JerseyTest I've managed to load the Spring context in my tests, but I haven't figured out how to access the spring context. My setup looks like this:
public abstract class SpringJerseyTest extends JerseyTest {
public SpringJerseyTest() throws Exception {
super(new WebAppDescriptor.Builder("com.acme.resources")
.contextPath("/")
.contextParam("contextConfigLocation", "classpath:applicationContext.xml")
.servletClass(SpringServlet.class)
.contextListenerClass(ContextLoaderListener.class)
.build());
}
}
The setup is using the default Grizzly Web Container. I've never used Grizzly before, but in Jetty I would do something like this:
public Object getSpringBean(String beanName) {
WebAppContext context = (WebAppContext) server.getHandler();
ServletContext sc = context.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(sc);
return applicationContext.getBean(beanName);
}
Could anyone point me in the right direction?
I am using a naive approach but works
public ResourceIT()
{
super(new WebAppDescriptor.Builder("amazingpackage")
.servletClass(SpringServlet.class)
.contextParam("contextConfigLocation", "classpath:/spring/context.xml")
.contextListenerClass(ContextLoaderListener.class)
.contextPath("context")
.build());
injectedBean = ContextLoaderListener
.getCurrentWebApplicationContext().getBean(InjectedBean.class);
}
Been using the solution described here for a week, and it's working fine.
I dont understand the need of JerseyTest that uses Spring bean, often your Spring Beans are Service/Dao layer and they have to be Unit test / Integration Test on their layer, using Mockito or DBUnit (integration Tests).
I have been unit Testing Jersey Resource classes using Sprig beans as mocks, this is because you have to isolate the tests, and test only Jersey stuff (and Json) in JerseyTest, not Service or Dao Layer., Yes I do pass my spring bean context, but the spring beans are only mocks, cause I don't want to test the spring beans in JerseyTests.
If you isolate you tests it would be easier to write and maintain your tests