nUnit testing a controller extension method - asp.net-mvc-5

UX controls framework I'm using requires an extension method on MVC controllers. A null object reference is thrown when nUnit tries to call that method (used in order to package a partial view into Json).
The author of the framework suggested calling that method through an interface, however that just postpones the null error.
Is there a way to test the ActionResult from a controller that uses an extension method?
The Controller Create() method returns the resulting partial from the extension method:
return Json(new { Content = viewRender.RenderPartialView(this, "ListItems/SimpleSyllabi", new[] { nS }) });
The extension method signature is
public static string RenderPartialView(this Controller controller, string viewName, object model = null, bool removeWhiteSpace = true);
Error is a simple:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Result StackTrace:
at System.Web.Mvc.VirtualPathProviderViewEngine.FindPartialView(ControllerContext controllerContext, String partialViewName, Boolean useCache)
at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClass2.<FindPartialView>b__0(IViewEngine e)
at System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths)
at System.Web.Mvc.ViewEngineCollection.FindPartialView(ControllerContext controllerContext, String partialViewName)
at Omu.AwesomeMvc.ControllerExtensions.RenderView(Controller controller, String viewName, Object model, String master, Boolean partial, Boolean removeWhiteSpace)
at Omu.AwesomeMvc.ControllerExtensions.RenderPartialView(Controller controller, String viewName, Object model, Boolean removeWhiteSpace)
at Flipprs.nUnitHelpers.Awesome.ViewRender.RenderPartialView(Controller controller, String viewName, Object model, Boolean removeWhiteSpace) in A:\Stephan\Source\Workspaces\AchievementCards\Develop-Payment(v0.0.11.0)\Flipprs.Web\Helpers\Awesome\nUnitHelpers.cs:line 17
at Flipprs.Controllers.SyllabusAjaxListController.Create(SyllabusCreateViewModel scvm) in A:\Stephan\Source\Workspaces\AchievementCards\Develop-Payment(v0.0.11.0)\Flipprs.Web\Controllers\SyllabusAjaxListController.cs:line 217
at Flipprs.Tests.Controllers.SyllabusAjaxListControllerTest.SyllabusAjaxListController_CreatePUT_ReturnsJson(String HTTPreqAUEmail) in A:\Stephan\Source\Workspaces\AchievementCards\Develop-Payment(v0.0.11.0)\Flipprs.Tests\Controllers\SyllabusAjaxListControllerTest.cs:line 484
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.
The Integration Test 'Setup':
private IViewRender viewRender;
viewRender = new ViewRender();
controller = new SyllabusAjaxListController(viewRender, photoPlaceholderService, activityService, syllabusService,
userService, organisationService, userManager);
Then in the test (excerpts)
[Test, Sequential]
public void SyllabusAjaxListController_CreatePUT_ReturnsJson()
{
ActionResult result_ar = controller.Create(validModel);
JsonResult result = result_ar as JsonResult;
}
Integration Test Mocks
Mock<ControllerContext> controllerContext;
Mock<HttpContext> httpContext;
Mock<HttpContextBase> contextBase;
Mock<HttpRequestBase> httpRequest;
Mock<HttpResponseBase> httpResponse;
Mock<IIdentity> identity;
Mock<IPrincipal> principal;
Mock<GenericPrincipal> genericPrincipal;

It appears the subject under test may be tightly coupled to 3rd party implementation concerns that make testing it in isolation difficult.
I suggest mocking the view render abstraction referred to in your original statement
public interface IViewRender {
string RenderPartialView(Controller controller, string viewName, object model = null, bool removeWhiteSpace = true);
}
to return a string when invoked so that the method under test can flow to completion and you can assert you expected behavior.
//Arrange
//...
var viewRenderMock = new Mock<IViewRender>(); //Using Moq mocking framework
viewRenderMock
.Setup(_ => _.RenderPartialView(It.IsAny<Controller>(), It.IsAny<string>(), It.IsAny<object>(), true))
.Returns("some fake view string");
//...
var controller = new SyllabusAjaxListController(viewRenderMock.Object,...) {
//...
};
//Act
var result = controller.Create(validModel) as JsonResult;
//Assert
result.Should().NotBeNull(); //FluentAssertions
//...other assertions.

Related

MockMvc fails because of method invocation inside the controller method

I try to mock a controller which contains a util method inside even though I mock the util method, the mvcMock ignore the result from the when(...) and call the method again with empty parameters which lead to nullpointerexception
How I can ship the call of
when(utilMock.getOperatorsAdNameWrapper(userName, adNames)).thenReturn(roleSet);
with the mockMvc.perform?
#GetMapping(value = {"/wellbore"})
public String wellboreForm(Model model, #RequestParam("mode") String mode, HttpServletRequest request) {
Set<String> operators = new LinkedHashSet<>();
String userName = (String) request.getSession().getAttribute("userName");
Set<String> operatorsSet = (HashSet<String>) request.getSession().getAttribute("userRoles");
Set<String> operatorsAdName = util.getOperatorsAdNameWrapper(userName, operatorsSet);
operatorsAdName.forEach(adName -> {
Query query = new Query()
.setClassname(Wellbore.CLASS)
.eq(Wellbore.operatorsGroup, adName);
operators.addAll(getWellboresNameList(query));
});
model.addAttribute("wellboreDataList", operators);
model.addAttribute("wellboreData", new WellboreForm());
return "ui/selectWellbore";
}
public static Set<String> getOperatorsAdName(String userName, Set<String> operatorsAdName) {
operatorsAdName.removeIf(x -> x.equals(userName)
|| x.equals("SCOUT")
|| x.equals("GTO")
|| x.equals("KADME")
|| x.equals("offline_access")
|| x.equals("uma_authorization"));
return operatorsAdName;
}
public Set<String> getOperatorsAdNameWrapper(String userName, Set<String> operatorsAdName) {
return getOperatorsAdName(userName,operatorsAdName);
}
#Mock
private Util utilMock;
#Test
#DisplayName("GET /wellbore - Select Wellbore")
void testMockMvc() throws Exception {
HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
when(req.getAttribute("userName")).thenReturn("abcd");
String userName = (String) req.getAttribute("userName");
//Here I get the correct result Result
when(utilMock.getOperatorsAdNameWrapper(userName, adNames)).thenReturn(roleSet);
//another call made here with empy parameters to utilMock.getOperatorsAdNameWrapper("", null)
mockMvc.perform(get("/wellbore").param("mode","selectWellbore")
.sessionAttr("wellboreDataList", new LinkedHashSet<>())
.sessionAttr("wellboreData", new WellboreForm())
)
.andExpect(status().isOk())
.andExpect(view().name("ui/selectWellbore"))
.andExpect(model().attribute("wellboreDataList", hasSize(2)));
}
1) In the Controller move the line:
util.getOperatorsAdNameWrapper(userName, operatorsSet);
into a package level method:
Set<String> getOperatorsAdNameWrapper(userName, operatorsSet){
return util.getOperatorsAdNameWrapper(userName, operatorsSet);
}
2) In your test use SpyBean:
#SpyBean
private Controller controllerSpy;
#Test
#DisplayName("GET /wellbore - Select Wellbore")
void testMockMvc() throws Exception {
doReturn(roleSet).when(controllerSpy).getOperatorsAdNameWrapper(userName, adNames);
The general gist is that you cannot mock a static call with vanilla Mockito. You have to refactor a bit first.
The Problem was with the Util class
since I am using mockmvc as unit testing, not as integration test by standaloneSetup
mockMvc = MockMvcBuilders
//To avoid loading springContext
.standaloneSetup(controller)
.setViewResolvers(viewResolver())
.build();
so the Util class not loaded to the context to solve this you have to option
Move the wrapper method in the util class to the service class and from there you can wrapper the static method in the Util class
Add the util class to the controller constructor

JSF with custom Annotation

I am using primefaces version 5 and I am adding messages regarding to a specific actions like save :
public void save(Tenant tenant) {
tenantDao.save(tenant);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Save success"));
}
Since I had a lot of these actions I tried to simplify this by creating a custom annotation called Message:
#Target(Runtime)
#Retention(Method)
public #interface Message {
String value();
}
and in my dao class :
public class TenantDao {
#Message("Saved Successfully")
public Tenant save(Tenant t) {
return em.save(t);
}
}
To read this annotation I have overridden the ELResolver the method invoke
public Object invoke(ELContext context,
Object base,
Object method,
Class<?>[] paramTypes,
Object[] params) {
Object result = super.invoke(context,method,paramTypes,params);
Method m = base.getClass().getMethod(method,paramTypes);
if(m.getAnnotation(Message.class) != null) {
addMessahe(m.getAnnotation(Message.class).value());
}
return result;
}
This was called in property (rendered, update, ..) but not in action listener
After a lot of debugging I discovered that theactionListener is called from MethodExpression class. So, I wrapped the MethodExpression class, and override the method invoke.
The problem now is that there are no way to retreive the class Method from MethodExpression class, also if I used the expression #{tenantDao.save(tenant)} the method getMethodInfo from MethodExpression will throw an exception.
Are there any way to read tAnnotation from any jsf context ?
I know that using Spring with AOP may solve this but I am not using Spring now.
Thanks

Using DynamicObject (IDynamicMetaObjectProvider) as a component of a static type leads to infinite loop

I'm trying to create a dynamic object that can be used as a component of a static object. Here is a contrived example of what I'm trying to accomplish.
Here is the dynamic component:
public class DynamicComponent : DynamicObject
{
public override bool TryInvokeMember(
InvokeMemberBinder binder,
object[] args,
out object result)
{
result = "hello";
return true;
}
}
And here is a class where inheriting from DynamicObject isn't an option...assume that there is some third party class that I'm forced to inherit from.
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
var result = component.GetMetaObject(parameter);
return result;
}
}
The direct usage of DynamicComponent works:
dynamic dynamicComponent = new DynamicComponent();
Assert.AreEqual(dynamicComponent.AMethod(), "hello");
However, forwarding the GetMetaObject through AStaticComponent causes some form of an infinite loop.
dynamic dynamicComponent = new AStaticComponent();
Assert.AreEqual(dynamicComponent.AMethod(), "hello"); //causes an infinite loop
Anyone know why this occurs?
And if it's some baked in behavior of DynamicObject that I cannot change, could someone provide some help on how to create a IDynamicMetaObjectProvider from scratch to accomplish a component based dynamic object (just something to get things started)?
I think the problem is that the Expression parameter passed to GetMetaObject represents the target of the dynamic invocation (i.e. the current object). You are passing the outer object to the call on component.GetMetaObject, so the returned meta object is trying to resolve the call to AMethod on the outer object instead of itself, hence the infinite loop.
You can create your own meta object which delegates to the inner component when binding member invocations:
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new DelegatingMetaObject(component, parameter, BindingRestrictions.GetTypeRestriction(parameter, this.GetType()), this);
}
private class DelegatingMetaObject : DynamicMetaObject
{
private readonly IDynamicMetaObjectProvider innerProvider;
public DelegatingMetaObject(IDynamicMetaObjectProvider innerProvider, Expression expr, BindingRestrictions restrictions)
: base(expr, restrictions)
{
this.innerProvider = innerProvider;
}
public DelegatingMetaObject(IDynamicMetaObjectProvider innerProvider, Expression expr, BindingRestrictions restrictions, object value)
: base(expr, restrictions, value)
{
this.innerProvider = innerProvider;
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
var innerMetaObject = innerProvider.GetMetaObject(Expression.Constant(innerProvider));
return innerMetaObject.BindInvokeMember(binder, args);
}
}
}
#Lee's answer is really useful, I wouldn't have known where to get started without it. But from using it in production code, I believe it has a subtle bug.
Dynamic calls are cached at the call site, and Lee's code produces a DynamicMetaObject which effectively states that the inner handling object is a constant. If you have a place in your code where you call a dynamic method on an instance of AStaticObject, and later the same point in the code calls the same method on a different instance of AStaticObject (i.e. because the variable of type AStaticObject now has a different value) then the code will make the wrong call, always calling methods on the handling object from the first instance encountered at that place in the code during that run of the code.
This is a like-for-like replacement, the key difference being the use of Expression.Field to tell the dynamic call caching system that the handling object depends on the parent object:
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new DelegatingMetaObject(parameter, this, nameof(component));
}
private class DelegatingMetaObject : DynamicMetaObject
{
private readonly DynamicMetaObject innerMetaObject;
public DelegatingMetaObject(Expression expression, object outerObject, string innerFieldName)
: base(expression, BindingRestrictions.Empty, outerObject)
{
FieldInfo innerField = outerObject.GetType().GetField(innerFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
var innerObject = innerField.GetValue(outerObject);
var innerDynamicProvider = innerObject as IDynamicMetaObjectProvider;
innerMetaObject = innerDynamicProvider.GetMetaObject(Expression.Field(Expression.Convert(Expression, LimitType), innerField));
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
return binder.FallbackInvokeMember(this, args, innerMetaObject.BindInvokeMember(binder, args));
}
}
}

How can I cast a object which is instantiated by reflection to its real type?

Recently I'm developing a tiny framework for myself,
and I met this problem:
How can I do things like follow:
void object CreateDictionary(Type dictionaryType)
{
object dict = dictionaryType.GetConstructor(new Type[] {}).Invoke(new object[] {});
// Cast dict to its real type here so that I can add key-value-pairs to it.
...
}
The dictionaryType is the type of some kind of Dictionary, and is got via reflection.
I have no idea about the full type because I don't know the generic attributes until runtime.
I've also tried changing the declaration object dict to var dict, but it does not work either.
You cannot do this. But, you know that this is some kind of Dictionary, so you can cast it to IDictionary and use methods of IDictionary.
object CreateDictionary(Type dictionaryType)
{
object dict = dictionaryType.GetConstructor(new Type[] {}).Invoke(new object[] {});
var idictionary = (IDictionary)dict;
idictionary.Add(key, value);
}
If your all this dictionaries is inherited from one class, you can cast it to this class and use methods of this class.
By the way, it is simpler to get instance of Type through:
object obj = Activator.CreateInstance(type);
OK, I managed to solve this problem at last.
Finally I noticed that what I want to do is not about casting,
but calling method.
Maybe there are better solutions than mine.
Anyway, I'd like to share my solution.
First, create an extension class for object (this is weird though):
public static class ReflectionHelper
{
public static object InvokeInstanceMethod(this object invoker, string methodName, params object[] parameters)
{
MethodInfo[] methods = invoker.GetType().GetMethods();
foreach (MethodInfo method in methods)
{
ParameterInfo[] paramInfos = method.GetParameters();
if (method.Name == methodName && paramInfos.Length == parameters.Length)
{
for (int i = 0; i < parameters.Length; i++)
{
if (!paramInfos[i].ParameterType.IsAssignableFrom(parameters[i].GetType()))
{
throw new MissingMethodException();
}
}
return method.Invoke(invoker, parameters);
}
}
throw new MissingMethodException();
}
}
This extension method allows me to call methods like this:
anyInstance.InvokeInstanceMethod("MethodName", param1, param2, ...);
Because all types, excluding Object itself, are derived from Object, this method can be cal on any instance of any type.
Then I use this method:
object dict = dictionaryType.CreateInstance(); // The method CreateInstance() is also an extension
dict.InvokeInstanceMethod("Add", key, val);

Handling Serialization Exceptions in ServiceStack

I am using ServiceStack to create a service which accepts request from and HTML form (POSTed). One of the DTO properties is an Enum, and when the input doesn't match the Enum members, I get the following exception:
Error occured while Processing Request: KeyValueDataContractDeserializer: Error converting to type: Requested value 'MyValue' was not found.
System.Runtime.Serialization.SerializationException: KeyValueDataContractDeserializer: Error converting to type: Requested value 'MyValue' was not found. ---> System.ArgumentException: Requested value 'MyValue' was not found.
at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
at ServiceStack.ServiceModel.Serialization.StringMapTypeDeserializer.PopulateFromMap(Object instance, IDictionary`2 keyValuePairs)
How can I intercept this exception and handle it myself in my service code?
There are a couple of ways to handle this situation:
You can make the DTO Enum property a string (since everything can successfully deserialize into a string :) and then convert that yourself manually i.e.
using ServiceStack.Common; //ToEnum<> is an extension method
public class RequestDto
{
public string EnumString { get; set; }
}
public override object OnGet(RequestDto request)
{
MyEnum defaultValue = MyEnum.None;
try {
defaultValue = request.EnumString.ToEnum<MyEnum>();
} catch {}
}
The other alternative is to completely remove it from the request DTO and get value manually from the IHttpRequest Context like:
public class RequestDto {}
public override object OnGet(RequestDto request)
{
MyEnum enumValue = MyEnum.DefaultValue;
try {
var enumStr = base.RequestContext.Get<IHttpRequest>().QueryString["EnumString"];
enumValue = enumStr.ToEnum<MyEnum>();
} catch {}
}
I generally discourage the use of enums on DTOs for many reasons, the primary one being on XML/SOAP endpoints the XSD treats them as a restricted set of values which is a pain in when trying iteratively to evolve your web services as you will need to re-gen the clients to add a new value.
By convention the way I deal with it is to have all enums as strings but provide some metadata on the DTO which points to the target type (which helps in VS.NET/R# navigation and metadata tools).
public class RequestDto
{
[References(typeof(MyEnum))]
public string EnumString { get; set; }
}

Resources