Test case for Struts2 2.3.24 using Strut2SpringTestCase (request object is coming as null) - unit-testing

I am trying to write unit test cases for my Struts2 action classes. My Test class extends SpringStrutsTestCase class. I am able to set the request object and able to get the action and action is also getting called but when in action it tries to get the parameters set in request object it throws null pointer exception i.e. request object is going as null. Below is my what my test class looks like. Any help is really appreciated.
import org.apache.struts2.StrutsSpringTestCase;
import org.junit.Test;
import com.opensymphony.xwork2.ActionProxy;
public class testClass extends StrutsSpringTestCase {
#Test
public void test1() throws Exception {
try {
request.setParameter("p1", "v1");
request.setParameter("p2", "v2");
ActionProxy proxy = getActionProxy("/actionName");
MyActionClass loginAction = (MyActionClass) proxy.getAction();
loginAction.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public String[] getContextLocations() {
String[] arr = new String[] { "one.xml", "two.xml", "three.xml" };
return arr;
}
}
Here is my action class.
public class MyAction extends ActionSupport{
private String p1;
private String p2;
/*
Gettere and Setters of p1 and p2
*/
public String execute() throws Exception {
// return "success";
logger.info("Login Action Called");
String pv1= (String) request.getParameter("p1");// If I get value using this.pv1 it works fine but with this code it doesn't.
String pv2= (String) request.getParameter("p2");
return "success";
}
}

In order to test an action call you need to call execute method of ActionProxy. By calling execute of your action you are just invoking that particular method of the action class and not S2 action along with the interceptors, results, etc.
The correct way would be:
ActionProxy proxy = getActionProxy("/actionName");
proxy.execute();
BTW if you're using JUnit 4 there is StrutsSpringJUnit4TestCase which you should use instead of StrutsSpringTestCase.

Related

How to mock customized logger with static keyword using Mockito?

I have created customized logging library named "StandardLogger" in which I am using logback for logging. Now I want to mock it in unit test but I am unable to do it.
Function I want to mock is static
public static String getHostOrDefault(String url, String defaultHost) {
try {
return new URL(url).getHost();
} catch (MalformedURLException e) {
logger.error("ConfigurationProvider", "getHostOrDefault", "Exception returning default host : "+ defaultHost + " Exception : "+e);
}
return defaultHost;
}
Class name and field
#Context
public class ConfigurationProvider {
private static final StandardLogger logger = new StandardLogger("CATS");
My Test class with unit test
class ConfigurationProviderTest {
#InjectMocks
ConfigurationProvider configurationProvider;
#Mock
private StandardLogger logger= new StandardLogger("CATS");
#Test
void thatGetHostOrDefaultReturnsHost() {
Mockito.doNothing().when(logger).info(Mockito.anyString(),Mockito.anyString(),Mockito.anyString());
String hostOrDefault = ConfigurationProvider.getHostOrDefault("http://abc.host:9433", "host");
assertThat(hostOrDefault, is("abc.host"));
}
Now when I am running it in debug mode logger object is NULL .
First of all, in the class under test you aren't injecting the logger. This means that you cannot inject it from the junit either. And exactly this happens: your logger is null in your class under test!
The second problem faces to you is about static methods. I've never been able to mock static method without using PowerMockito, even if here there is an interesting article that says that you can do it.

Unit testing of SimpleChannelInboundHandler<FullHTTPRequest> in netty

I am new to netty framework.We have a API Handler implementing SimpleChannelInboundHandler and overriding the ChannelRead0 function that takes ChannelHandlerContext and the FullHTTPRequest.Now I need to do unit testing mocking the inputs.
Can anyone help me with this.
Lets assume I want to test my MyContentExtractionHandler, which looks like this:
public class MyContentExtractionHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
#Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
int contentLenght = msg.content().capacity();
byte[] content = new byte[contentLenght];
msg.content().getBytes(0, content);
ctx.fireChannelRead(new String(content));
}
}
I will create a regular DefaultFullHttpRequest and use mockito to mock a ChannelHandlerContext. My unit test would look like this:
public class MyContentExtractionHandlerTest {
#Mock
ChannelHandlerContext mockCtx = BDDMockito.mock(ChannelHandlerContext.class);
MyContentExtractionHandler myContentExtractorHandler = new MyContentExtractionHandler();
#Test
public void myTest() throws Exception {
String content = "MyContentHello";
DefaultFullHttpRequest fullHttpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/my /uri", Unpooled.copiedBuffer(content.getBytes()));
myContentExtractorHandler.channelRead(mockCtx, fullHttpRequest);
BDDMockito.verify(mockCtx).fireChannelRead(content); //verify that fireChannelRead was called once with the expected result
}
}
Most possibly, your SimpleChannelInboundHandler will be the final handler. So instead of checking for fireChannelRead() check for whatever method you call after reading the message.

How to use Moq to Prove that the Method under test Calls another Method

I am working on a unit test of an instance method. The method happens to be an ASP.NET MVC 4 controller action, but I don't think that really matters much. We just found a bug in this method, and I'd like to use TDD to fix the bug and make sure it doesn't come back.
The method under test calls a service which returns an object. It then calls an internal method passing a string property of this object. The bug is that under some circumstances, the service returns null, causing the method under test to throw a NullReferenceException.
The controller uses dependency injection, so I have been able to mock the service client to have it return a null object. The problem is that I want to change the method under test so that when the service returns null, the internal method should be called with a default string value.
The only way I could think to do this is to use a mock for the class under test. I want to be able to assert, or Verify that this internal method has been called with the correct default value. When I try this, I get a MockException stating that the invocation was not performed on the mock. Yet I was able to debug the code and see the internal method being called, with the correct parameters.
What's the right way to prove that the method under test calls another method passing a particular parameter value?
I think there's a code smell here. The first question I'll ask myself in such a situation is, is the "internal" method really internal/ private to the controller under test. Is it the controller's responsibility to do the "internal" task? Should the controller change when the internal method's implementation changes? May be not.
In that case, I would pull out a new targeted class, which has a public method which does the stuff which was until now internal to the controller.
With this refactoring in place, I would use the callback mechanism of MOQ and assert the argument value.
So eventually, you will end up mocking two dependancies:
1. The external service
2. The new targeted class which has the controller's internal implementation
Now your controller is completely isolated and can be unit tested independently. Also, the "internal" implementation becomes unit testable and should have its own set of unit tests too.
So your code and test would look something like this:
public class ControllerUnderTest
{
private IExternalService Service { get; set; }
private NewFocusedClass NewFocusedClass { get; set; }
const string DefaultValue = "DefaultValue";
public ControllerUnderTest(IExternalService service, NewFocusedClass newFocusedClass)
{
Service = service;
NewFocusedClass = newFocusedClass;
}
public void MethodUnderTest()
{
var returnedValue = Service.ExternalMethod();
string valueToBePassed;
if (returnedValue == null)
{
valueToBePassed = DefaultValue;
}
else
{
valueToBePassed = returnedValue.StringProperty;
}
NewFocusedClass.FocusedBehvaior(valueToBePassed);
}
}
public interface IExternalService
{
ReturnClass ExternalMethod();
}
public class NewFocusedClass
{
public virtual void FocusedBehvaior(string param)
{
}
}
public class ReturnClass
{
public string StringProperty { get; set; }
}
[TestClass]
public class ControllerTests
{
[TestMethod]
public void TestMethod()
{
//Given
var mockService = new Mock<IExternalService>();
mockService.Setup(s => s.ExternalMethod()).Returns((ReturnClass)null);
var mockFocusedClass = new Mock<NewFocusedClass>();
var actualParam = string.Empty;
mockFocusedClass.Setup(x => x.FocusedBehvaior(It.IsAny<string>())).Callback<string>(param => actualParam = param);
//when
var controller = new ControllerUnderTest(mockService.Object, mockFocusedClass.Object);
controller.MethodUnderTest();
//then
Assert.AreEqual("DefaultValue", actualParam);
}
}
Edit: Based on the suggestion in the comments to use "verify" instead of callback.
Easier way to verify the parameter value is by using strict MOQ behavior and a verify call on the mock after system under test is executed.
Modified test could look like below:
[TestMethod]
public void TestMethod()
{
//Given
var mockService = new Mock<IExternalService>();
mockService.Setup(s => s.ExternalMethod()).Returns((ReturnClass)null);
var mockFocusedClass = new Mock<NewFocusedClass>(MockBehavior.Strict);
mockFocusedClass.Setup(x => x.FocusedBehvaior(It.Is<string>(s => s == "DefaultValue")));
//When
var controller = new ControllerUnderTest(mockService.Object, mockFocusedClass.Object);
controller.MethodUnderTest();
//Then
mockFocusedClass.Verify();
}
"The only way I could think to do this is to use a mock for the class under test."
I think you should not mock class under test. Mock only external dependencies your class under test has. What you could do is to create a testable-class. It would be a class which derives from your CUT and here you can catch the calls to the another method and verify it's parameter later. HTH
Testable class in the example is named MyTestableController
Another method is named InternalMethod.
Short example:
[TestClass]
public class Tests
{
[TestMethod]
public void MethodUnderTest_WhenServiceReturnsNull_CallsInternalMethodWithDefault()
{
// Arrange
Mock<IService> serviceStub = new Mock<IService>();
serviceStub.Setup(s => s.ServiceCall()).Returns((ReturnedFromService)null);
MyTestableController testedController = new MyTestableController(serviceStub.Object)
{
FakeInternalMethod = true
};
// Act
testedController.MethodUnderTest();
// Assert
Assert.AreEqual(testedController.SomeDefaultValue, testedController.FakeInternalMethodWasCalledWithThisParameter);
}
private class MyTestableController
: MyController
{
public bool FakeInternalMethod { get; set; }
public string FakeInternalMethodWasCalledWithThisParameter { get; set; }
public MyTestableController(IService service)
: base(service)
{ }
internal override void InternalMethod(string someProperty)
{
if (FakeInternalMethod)
FakeInternalMethodWasCalledWithThisParameter = someProperty;
else
base.InternalMethod(someProperty);
}
}
}
The CUT could look something like this:
public class MyController : Controller
{
private readonly IService _service;
public MyController(IService service)
{
_service = service;
}
public virtual string SomeDefaultValue { get { return "SomeDefaultValue"; }}
public EmptyResult MethodUnderTest()
{
// We just found a bug in this method ...
// The method under test calls a service which returns an object.
ReturnedFromService fromService = _service.ServiceCall();
// It then calls an internal method passing a string property of this object
string someStringProperty = fromService == null
? SomeDefaultValue
: fromService.SomeProperty;
InternalMethod(someStringProperty);
return new EmptyResult();
}
internal virtual void InternalMethod(string someProperty)
{
throw new NotImplementedException();
}
}

Mockito: Verify if Spring Data JPA delete()-method is called

So, I am relatively new to unit-testing and especially mockito and am trying to figure out how to test the following scenario in Spring WebMVC:
This is my Service Class (simplified):
#Service
public class MyServiceImpl implements MyService {
#Resource
private MyCrudRepository myCrudRepository;
/**
* Method to delete(!) an entry from myTable.
*
*/
#Transactional
public void removeTableEntry(Long entryOid, String userId) throws Exception {
if (myCrudRepository.findOne(entryOid) != null) {
myCrudRepository.delete(entryOid);
log.info("User ID: " + userId + " deleted Entry from myTable with Oid " + entryOid + ".");
} else {
log.error("Error while deleting Entry with Oid: "+ entryOid + " from User with ID: " + userId);
throw new Exception();
}
}
}
Here I call the "built-in" delete-method of Spring Data JPA crudrepository, meaning no custom implementation in the repository itself (Using OpenJPA).
This is my simplified Test-Class:
#RunWith(MockitoJUnitRunner.class)
public class MyServiceImplTest {
final String USERID = "Testuser";
MyServiceImpl myService;
#Mock
MyCrudRepository myCrudRepository;
#Before
public void setUp() {
myService = new MyServiceImpl();
ReflectionTestUtils.setField(myService, "myCrudRepository", myCrudRepository);
}
//works (as expected? not sure)
#Test(expected = Exception.class)
public void testRemoveSomethingThrowsException() throws Exception {
doThrow(Exception.class).when(myCrudRepository).delete(anyLong());
myService.removeSomething(0l, USERID);
}
//does not work, see output below
#Test
public void testRemoveSomething() throws Exception {
verify(myCrudRepository, times(1)).delete(anyLong());
myService.removeSomething(0l, USERID);
}
//...
}
So, I try to verify that delete is called in testRemoveSomething(), but instead I get the following output:
Wanted but not invoked:
myCrudRepository.delete(<any>);
-> at myPackage.testRemoveSomething(MyServiceImplTest.java:98)
Actually, there were zero interactions with this mock.
And I'm nearly out of ideas why, to be honest (thinking about the #Transactional, perhaps? But this didn't get me to the solution, yet). May be that I'm completely wrong here (architectural, dunno) - if so, please feel free to give me a hint :)
It would be great to get some help here! Thanks in advance.
Your method fist calls findOne(), check if that returns something, and then calls delete(). So your test should first make sure that findOne returns something. Otherwise, the mock repository's findOne() method returns null by default. Moreover, you should verify that the call has been executed after it has been executed. Not before.
#Test
public void testRemoveSomething() throws Exception {
when(myCrudRepository.findOne(0L)).thenReturn(new TableEntry());
myService.removeTableEntry(0l, USERID);
verify(myCrudRepository, times(1)).delete(0L);
}
Also, you should use the #InjectMocks annotation rather than instantiating your service and injecting the repository using reflection.

Moq - how to verify method call which parameter has been cleaned (a list)

I've got the following code and I need help to write a unit test for it. I'm using Moq library.
Here's the deal. I have a business class with a dependency to a repository (interface), so I can use it to save my entities to the database. My entity is basically a list of strings. The method AddAndSave, from MyBusinessClass, grab the value it receives as a parameters, put it into the list and call Save method from IRepository. Then, I clear the list of my entity. The code below show this example (I've made it simple so I can explain it here).
There's a unit test, too.
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace TestesGerais
{
public class MyEntity
{
public MyEntity()
{
MyList = new List<string>();
}
public List<string> MyList { get; set; }
}
public interface IRepository
{
void Save(MyEntity entity);
}
public class MyBusinessClass
{
public IRepository Repository { get; set; }
private MyEntity _entity = new MyEntity();
public void AddAndSave(string info)
{
_entity.MyList.Add(info);
Repository.Save(_entity);
_entity.MyList.Clear(); // for some reason I need to clear it
}
}
[TestClass]
public class UnitTest10
{
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<IRepository>();
MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object };
b.AddAndSave("xpto");
mock.Verify(m => m.Save(It.Is<MyEntity>(x => x.MyList[0] == "xpto")), Times.Exactly(1));
}
}
}
My unit-test check if the IRepository's Save method was called with its parameter (an entity) having one element in the list, and having the value "xpto" in this element.
When I run this test, it turns red with the error message "Test method TestesGerais.UnitTest10.TestMethod1 threw exception:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index".
Ok, this is caused by the list that has been cleaned. If I comment the line "_entity.MyList.Clear();", everything goes well.
My question is: how can I test this without commenting the "Clear" line in my business class, and making sure that my repository's method is called passing the specific value (entity with one element with value "xpto")?
Thanks
I've changed my unit test using the Callback feature of Moq. This way, I can setup the mock so when AddAndSave is called, the parameter it receives is saved into a variable from my unit test, and I can assert it later.
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<IRepository>();
string result = string.Empty;
mock.Setup(m => m.Save(It.IsAny<MyEntity>())).Callback((MyEntity e) => { result = e.MyList[0]; });
MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object };
b.AddAndSave("xpto");
Assert.AreEqual(result, "xpto");
}
You could split your method up a bit. "AddAndSave" isn't all it does. You could then just test the behaviour of the adding and saving bit in isolation.