Mock RouteData in RhinoMocks-MVC3 - rhino-mocks

How to Mock RouteData in RhinoMock?
I have to Mock this.
(RouteData.Values["id"].Tostring()!=null)
Thank you

Given that RouteData is of type IRouteData you can mock it like this:
[Test]
public void TestMockingConcreteClass()
{
MockRepository mockRepository = new MockRepository();
RouteData routeData = mockRepository.Stub<RouteData>();
routeData.Stub(r => r.Values["id"]).Return("XXX");
mockRepository.ReplayAll();
Assert.That(routeData.Values["id"].ToString(), Is.EqualTo("XXX"));
}

After lots of googling I got this to :
Declared at the Class Level
HttpContextBase httpContextMock;
ControllerBase controllerMock;
In the Constructor
mockRepository = new MockRepository();
httpContextMock = mockRepository.DynamicMock<HttpContextBase>();
controllerMock = mockRepository.DynamicMock<ControllerBase>();
In The Test Method:
var routeData = new RouteData();
routeData.Values.Add("id", "Value");
absenceController.ControllerContext = new ControllerContext(httpContextMock, routeData, controllerMock);
``

Related

Mocking ControllerBase.HttpContext.AuthenicateAsync() to return success using SAML2.0

I am trying to understand why HttpContext.AuthenticateAsync() method fails when I set the httpContext using the following code
public static void SetMockAuthenticatedControllerContext(this Controller controller,string userName)
{
var httpContext = MockHttpContext(userName);
var controllerContext = new ControllerContext
{
HttpContext= httpContext,
RouteData=new Microsoft.AspNetCore.Routing.RouteData()
};
controller.ControllerContext = controllerContext;
}
public static HttpContext MockHttpContext(string userName)
{
var context = new Mock<HttpContext>();
var request = new Mock<HttpRequest>();
var response = new Mock<HttpResponse>();
var session = new Mock<ISession>();
var user = new Mock<ClaimsPrincipal>();
var identity = new Mock<ClaimsIdentity>();
var features = new Mock<IFeatureCollection>();
var authService = new Mock<IAuthenticationService>();
var prodvierServiceMock = new Mock<IServiceProvider>();
var authTicket = new AuthenticationTicket(new ClaimsPrincipal(), "External");
authService.Setup(c => c.AuthenticateAsync(It.IsAny<HttpContext>(), It.IsAny<string>()))
.Returns(Task.FromResult(AuthenticateResult.Success(authTicket)));
prodvierServiceMock.Setup(c => c.GetService(typeof(IAuthenticationService))).Returns(authService);
context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session.Object);
//context.Setup(ctx=>ctx.GetServerVariable(It.IsAny<string>())).Returns()
context.Setup(ctx => ctx.User).Returns(user.Object);
context.Setup(x => x.RequestServices).Returns(prodvierServiceMock.Object);
context.Setup(ctx => ctx.Features).Returns(features.Object);
context.Setup(ctx => ctx.User.Identity).Returns(identity.Object);
identity.Setup(x => x.IsAuthenticated).Returns(true);
identity.Setup(x => x.Name).Returns(userName);
return context.Object;
}
and I am calling this in my controller test class as
follows:
HttpContextFactory.SetMockAuthenticatedControllerContext(mycontrollerInstance,userName);
then
call
var result = controller.Index();
which throws the following error:
Unable to cast object of type 'Moq.Mock`1[Microsoft.AspNetCore.Authentication.IAuthenticationService]' to type 'Microsoft.AspNetCore.Authentication.IAuthenticationService
Please help me understand what i am doing wrong.
Thanks for the help.

Simple serialize ODataQueryOptions

I'm trying to:
[EnableQuery]
[HttpGet]
[ODataRoute("")]
public IHttpActionResult Get(ODataQueryOptions<UserODataModel> options)
{
var users = _repository.RetrieveOData();
var serialQuery = JsonConvert.SerializeObject(options, jsonOptions);
//save serialQuery somewhere
return Ok(users);
}
But got
Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'ReadTimeout' on 'Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream'.'
"Timeouts are not supported on this stream."
I know there is already a question about serialize Stream:
Newtonsoft Json.net - how to serialize content of a stream?
But in this case i can't "extract stream value" from ODataQueryOptions, or can I?
Some ideia?
Since we work on the same company, if anyone is interested, we found a way, maybe not the pretty way, to serialize an ODataQueryOptions:
public static ODataQueryOptions DeserializeQueryOptions(SerializedQueryOptions options)
{
var uri = new Uri(teste.OriginalUri);
var model = ODataConfig.Model; //GetEdmModel
var segment = model.EntityContainer.FindEntitySet(options.EdmType);
var newPath = new Microsoft.AspNet.OData.Routing.ODataPath(new EntitySetSegment(segment));
var httpConfiguration = new HttpConfiguration();
httpConfiguration.EnableDependencyInjection();
var request = new HttpRequestMessage(HttpMethod.Get, uri)
{
Properties =
{
{ HttpPropertyKeys.HttpConfigurationKey, httpConfiguration },
}
};
var context = new ODataQueryContext(model, options.EntityType, newPath);
var oDataQueryOptions = new ODataQueryOptions(context, request);
return oDataQueryOptions;
}
public static SerializedQueryOptions SerializeQueryOptions(ODataQueryOptions options)
{
return new SerializedQueryOptions
{
OriginalUri = options.Request.RequestUri.AbsoluteUri,
EdmType = options.Context.NavigationSource.Name,
EntityType = options.Context.ElementClrType
};
}
After you serialize it to an object you can serialize it to a JSON string:
var queryOptionsSerialized = new SerializedQueryOptions()
{
OriginalUri = "http://localhost:25723/odata/users?$skip=0&$top=2&$orderby=fullName&$count=true",
EdmType = "users",
EntityType = typeof(UserODataModel)
};
var json = JsonConvert.SerializeObject(queryOptionsSerialized);
var deserialized = JsonConvert.DeserializeObject<SerializedQueryOptions>(json);
var options = ODataQueryOptionsHelper.DeserializeQueryOptions(deserialized);
In case One is not using OData routing or using an ApiController (not ODataController),
modify the way of Obtaining ODataPath to:
ODataUriParser parser = new ODataUriParser(model, serviceRoot, requestUri);
ODataPath path = parser.ParsePath();
//var newPath = new Microsoft.AspNet.OData.Routing.ODataPath(new EntitySetSegment(segment));
Microsoft.AspNet.OData.Routing.ODataPath newPath = new Microsoft.AspNet.OData.Routing.ODataPath(path.FirstOrDefault());
where the serviceRoot is the Url part other that the path defined in the model.

ASP.NET CORE using ADO.NET with AutoMapper

What is the proper way of using AutoMapper with ADO.NET in ASP.NET Core in generic way?
Also the SQL query has the same column names as in class of <T>
In specified example variable result is always empty list, so automapper could not map object properties to DbDataReader columns.
public class CustomDbContext : BaseRepository
{
readonly DbConnection dbConn;
public CustomDbContext(RepoDbContext context) : base(context)
{
dbConn = context.Database.GetDbConnection();
}
public async Task<List<T>> Get<T>(string sql) where T : class
{
var config = new AutoMapper.MapperConfiguration(cfg =>
{
cfg.CreateMap<DbDataReader, List<T>>();
});
var mapper = config.CreateMapper();
await dbConn.OpenAsync();
using (var command = dbConn.CreateCommand())
{
command.CommandText = sql;
var reader = await command.ExecuteReaderAsync();
var result = new List<T>();
if (reader.HasRows)
{
await reader.ReadAsync();
result = mapper.Map<DbDataReader, List<T>>(reader);
}
reader.Dispose();
return result;
}
}
}
Should I specify more detailed AutoMapper configuration or it can't be done this way?
Try using interfaces as IDataReader and IEnumerable instead of classes DbDataReader and List.
public async Task<List<T>> Get<T>(string sql) where T : class
{
var config = new AutoMapper.MapperConfiguration(cfg =>
{
cfg.CreateMap<IDataReader, IEnumerable<T>>();
});
var mapper = config.CreateMapper();
await dbConn.OpenAsync();
using (var command = dbConn.CreateCommand())
{
command.CommandText = sql;
var reader = await command.ExecuteReaderAsync();
var result = new List<T>();
if (reader.HasRows)
{
await reader.ReadAsync();
result = mapper.Map<IDataReader, IEnumerable<T>>(reader).ToList();
}
reader.Dispose();
return result;
}
}

How to test model binder in ASP.Net MVC 6?

I'm trying to write a unit test for a custom model binder in ASP.Net MVC 6. It seems simple enough. The model binder has a single BindModelAsync method which takes a ModelBindingContext parameter.
In my unit test, I'm trying to figure out how to fake the ModelBindingContext. At first, I thought I could use the default constructor and set the properties on the object that I need. This works for all of the properties except ModelType which is not settable.
I then looked at the static ModelBindingContext.CreateBindingContext but it takes a bunch of scary looking parameters. Looking at how some of the model binding tests within the MVC repo are written, it seems like it is not possible for me to mock the ModelBindingContext.ModelType (unless maybe I copy/paste those 6 classes from Microsoft.AspNetCore.Mvc.TestCommon).
Is there something simple/easy I am missing?
I've had some success in getting it working for some simple form and query string values. AspNetCore.Mvc v1.1.3
private static DefaultModelBindingContext GetBindingContext(IValueProvider valueProvider, Type modelType)
{
var metadataProvider = new EmptyModelMetadataProvider();
var bindingContext = new DefaultModelBindingContext
{
ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = modelType.Name,
ModelState = new ModelStateDictionary(),
ValueProvider = valueProvider,
};
return bindingContext;
}
Using a query string provider
[TestMethod]
public async Task QueryStringValueProviderTest()
{
var binder = new MyModelBinder();
var queryCollection = new QueryCollection(
new Dictionary<string, StringValues>()
{
{ "param1", new StringValues("1") },
{ "param2", new StringValues("2") },
});
var vp = new QueryStringValueProvider(BindingSource.Query, queryCollection, CultureInfo.CurrentCulture);
var context = GetBindingContext(vp, typeof(MyModel));
await binder.BindModelAsync(context);
var resultModel = context.Result.Model as MyModel;
//TODO Asserts
}
Using a form collection provider
[TestMethod]
public async Task FormValueProviderTest()
{
var binder = new MyModelBinder();
var formCollection = new FormCollection(
new Dictionary<string, StringValues>()
{
{ "param1", new StringValues("1") },
{ "param2", new StringValues("2") }
});
var vp = new FormValueProvider(BindingSource.Form, formCollection, CultureInfo.CurrentCulture);
var context = GetBindingContext(vp, typeof(MyModel));
await binder.BindModelAsync(context);
var resultModel = context.Result.Model as MyModel;
//TODO asserts
}

Can I implement file download using MVC4's ApiController?

Using regular Controller I could do it by returning FileResult. The same doesn't seem to work with ApiController. Can it be done? Is it even a right thing to do?
Try this.
[HttpGet]
public HttpResponseMessage Get()
{
var file = HttpContext.Current.Server.MapPath("~/Images/accent.png");
var stream = new FileStream(file, FileMode.Open);
var content = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream)
};
content.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return content;
}
I have this working thanks to this question.
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
namespace Web.Controllers
{
//usage: /download/report
[RoutePrefix("download")]
public class DownloadController : ApiController
{
[HttpGet("report")]
public HttpResponseMessage Report()
{
using (var service = new Client())
{
var report = service.BuildReport();
return DownloadResponse(report, "Report.csv");
}
}
private static HttpResponseMessage DownloadResponse(string content, string fileName)
{
var downloadContent = new StringContent(content);
var mediaType = new MediaTypeHeaderValue("application/octet-stream");
var disposition= new ContentDispositionHeaderValue("attachment") { FileName = fileName };
downloadContent.Headers.ContentType = mediaType;
downloadContent.Headers.ContentDisposition = disposition;
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = downloadContent
};
return result;
}
}
}