Reference members in Moq lambda - moq

I have a function in a class that returns a value based on the state of a class property. In this example, I want HasName() to return true if Name is not null. I could simply do Returns(false), however I want it evaluate as a lambda so that it works properly if Name is modified during the test.
public interface IThing
{
string Name { get; set; }
bool HasName();
}
var mocks = new Dictionary<string, IThing>();
Mock<IThing> mockThing;
mockThing = new Mock<IThing>();
mockThing.SetupProperty(m => m.Name, "test");
mockThing.Setup(m => m.HasName()).Returns(() =>
{
return mockThing.Object.Name != null;
});
mocks["first"] = mockThing.Object;
mockThing = new Mock<IThing>();
mockThing.SetupProperty(m => m.Name, "test");
mockThing.Setup(m => m.HasName()).Returns(() =>
{
return mockThing.Object.Name != null;
});
mocks["second"] = mockThing.Object;
Console.WriteLine(mocks["first"].HasName());
mocks["first"].Name = null;
Console.WriteLine(mocks["first"].HasName());
The 2nd Console.WriteLine prints true instead of false due to scoping (referencing the 2nd mock). Resharper actually complains of "Access to modified closure". What is the correct way to do this?

Although your design a little bit strange but you can access the generated mock object with mockThing.Object in your Setup function:
mockThing.Setup(m => m.HasName()).Returns(() =>
{
return mockThing.Object.Name != null;
});
var thing = mockThing.Object;
var hasName = thing.HasName(); // true because Name returns "test"
thing.Name = null;
hasName = thing.HasName(); // false
The problem is that you are referencing the mockThing with your lambdas and then you are reasigning it. So both setup will end up using the same instance.
Use the mocks from the dictionary and it will work:
var mocks = new Dictionary<string, IThing>();
Mock<IThing> mockThing;
mockThing = new Mock<IThing>();
mocks["first"] = mockThing.Object;
mockThing.SetupProperty(m => m.Name, "test");
mockThing.Setup(m => m.HasName()).Returns(() =>
{
return mocks["first"].Name != null;
});
mockThing = new Mock<IThing>();
mocks["second"] = mockThing.Object;
mockThing.SetupProperty(m => m.Name, "test");
mockThing.Setup(m => m.HasName()).Returns(() =>
{
return mocks["second"].Name != null;
});
Console.WriteLine(mocks["first"].HasName());
mocks["first"].Name = null;
Console.WriteLine(mocks["first"].HasName());

Related

No service for type 'IdentityServer4.Configuration.IdentityServerOptions' has been registered. - Mocking HttpContext.SignInAsync

I'm trying to cover External auth with Unit Tests.
Mocked all dependencies including SignInAsync(). But execution fails with the message "No service for type 'IdentityServer4.Configuration.IdentityServerOptions' has been registered." when it hits SignInAsync().
Stack trace here
Test method.
public async Task CallBack_User_Is_Defined_In_AAD_ReturnChallenge()
{
var ticket = new AuthenticationTicket(TestUsers.Principal, "Test");
var result = AuthenticateResult.Success(ticket);
result.Properties?.Items.Add("returnUrl", "sign-callback");
result.Properties?.Items.Add("scheme", "aad");
authenticationService.Setup(c => c.AuthenticateAsync(It.IsAny<HttpContext>(), IdentityServerConstants.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(result)); ;
var serviceProviderMock = new Mock<IServiceProvider>();
serviceProviderMock
.Setup(_ => _.GetService(typeof(IAuthenticationService)))
.Returns(authenticationService.Object);
serviceProviderMock
.Setup(_ => _.GetService(typeof(IdentityOptions)))
.Returns(authenticationService.Object);
var identityServiceUserResponse = new IdentityServiceUserResponse
{
Email = TestUsers.Principal.FindFirstValue(ClaimTypes.Email),
CompanyID = "1",
Login = "john"
};
identityServiceAuthService.Setup(c => c.GetUserByExternalEmailAsync(It.IsAny<string>()))
.Returns(Task.FromResult(identityServiceUserResponse));
var authRequest = new AuthorizationRequest
{
Client = new Client { ClientId = "client" },
ValidatedResources = resourceValidationResult,
Parameters = { { "returnUrl", "signin-callback" } },
};
interactionService.Setup(i => i.GetAuthorizationContextAsync(It.IsAny<string>()))
.Returns(Task.FromResult(authRequest));
authenticationService
.Setup(_ => _.SignInAsync(It.IsAny<HttpContext>(), It.IsAny<string>(), It.IsAny<ClaimsPrincipal>(), It.IsAny<AuthenticationProperties>()))
.Returns(Task.FromResult((object)null));
controller = new ExternalController(configuration.Object, interactionService.Object,
identityServiceAuthService.Object, clientStore.Object, events.Object, logger.Object);
controller.ControllerContext = controller.CreateControllerContext(TestUsers.Principal);
controller.ControllerContext.HttpContext.RequestServices = serviceProviderMock.Object;
await controller.Callback();
}

Razor Pages get class Attributes in Unit Tests

currently I'm trying to check if there is a way to get the class names of all attributes on razor page classes.
I unit tests all my controllers to look for an AuthorizeFilter so that it is impossible to forget it
Currently this is how I do it via MVC (does not work in Razor Pages):
var values = actionDescriptorCollectionProvider
.ActionDescriptors
.Items
.OfType<ControllerActionDescriptor>()
.Select(a => new
{
a.DisplayName,
a.ControllerName,
a.ActionName,
AttributeRouteTemplate = a.AttributeRouteInfo?.Template,
HttpMethods = string.Join(", ", a.ActionConstraints?.OfType<HttpMethodActionConstraint>().SingleOrDefault()?.HttpMethods ?? new string[] { "any" }),
Parameters = a.Parameters?.Select(p => new
{
Type = p.ParameterType.Name,
p.Name
}),
ControllerClassName = a.ControllerTypeInfo.FullName,
ActionMethodName = a.MethodInfo.Name,
Filters = a.FilterDescriptors?.Select(f => new
{
ClassName = f.Filter.GetType().FullName,
f.Scope //10 = Global, 20 = Controller, 30 = Action
}),
Constraints = a.ActionConstraints?.Select(c => new
{
Type = c.GetType().Name
}),
RouteValues = a.RouteValues.Select(r => new
{
r.Key,
r.Value
}),
});
The problem is, that this code won't work with Razor Pages, i.e. FilterDescriptors is empty for PageActionDescriptor.
You need to use PageActionDescriptor for RazorPages instead of ControllerActionDescriptor:
var values = actionDescriptorCollectionProvider
.ActionDescriptors
.Items
.OfType<PageActionDescriptor>()
.Select(descriptor => new
{
// descriptor...,
// ...
});

Chain HTTP calls

I have a REST API that returns an array of appointments. For each item in this array I want to make an single call against another API to get more Information for the item.
this.httpClient.get(this.serverUrl, this.httpOptions.RequestOptions)
.map(res => res.json())
.map((items: Array<any>) => {
let list: Array<MettAppointmentModel> = [];
if (items) {
items.forEach(item => {
let model = new MettAppointmentModel();
model.Created = item.created;
model.CreatedBy = item.createdBy;
model.Date = item.date;
model.Id = item._id;
model.participated = this.httpClient.get(this.serverUrl + model.Id, this.httpOptions).map(response => return response.json());
list.push(model);
});
}
return list;
} );
I don't know how to get another call chained in this call
model.participated = this.httpClient.get(this.serverUrl + model.Id, this.httpOptions).map(response => return response.json());

How to display enum description or name in a grid row?

I am using the Kendo grid in my ASP.Net MVC application. If I have the following grid definition,
#(Html.Kendo().Grid(Model) //Bind the grid to ViewBag.Products
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.FullName);
columns.Bound(p => p.MyEnum)
})
.Groupable()
.Pageable()
.Sortable()
.Scrollable(scr => scr.Height(600))
.Filterable()
)
where one of the column is an Enum. My enum definition is:
public enum MyEnum
{
[Display(AutoGenerateField = false, Name = "My enum 1", Description = "My Enum 1")]
EnumOne,
[Display(Name = "My Enum 2")]
EnumTwo
}
How do I make it display "My Enum 1" or "My Enum 2" for each row?
Thanks in advance!
I recently ran into this problem and solved it by using
var someArrayOfValueAndText = new[] {new {
Id = 0, Description = "Foo"
}, new {
Id = 1, Description = "Bar"
}
.Columns(c.ForeignKey(m=> m.MyEnum, someArrayOfValueAndText, "Id","Description"))
instead of the .Bound method
I created an helper class containing some extension methods a while back:
public static class EnumExtensions
{
public static string GetDisplayName(this Enum enu)
{
var attr = GetDisplayAttribute(enu);
return attr != null ? attr.Name : enu.ToString();
}
public static string GetDescription(this Enum enu)
{
var attr = GetDisplayAttribute(enu);
return attr != null ? attr.Description : enu.ToString();
}
private static DisplayAttribute GetDisplayAttribute(object value)
{
Type type = value.GetType();
if (!type.IsEnum)
{
throw new ArgumentException(string.Format("Type {0} is not an enum", type));
}
// Get the enum field.
var field = type.GetField(value.ToString());
return field == null ? null : field.GetCustomAttribute<DisplayAttribute>();
}
}
It contains two methods for extracting the Name and Description of a Display attribute. The display name:
columns.Bound(p => p.MyEnum.GetDisplayName())
And for a description:
columns.Bound(p => p.MyEnum.GetDescription())
You have to add a using statement in your Web.config or in your view.
Update
What if you create a property for it in your model:
public string MyEnumName
{
get { return MyEnum.GetDisplayName(); }
}
Now you should be able to use:
columns.Bound(p => p.MyEnumName);
Henk's solution is good. But you can use filtering capability if you use ClientTemplate:
col.Bound(m => m.MyEnum) // this provides you filtering
.ClientTemplate("#: MyEnumName #") // this shows a name of enum
For more information about kendo ui templates see: http://docs.telerik.com/kendo-ui/framework/templates/overview
I use #user1967246 method and would like to explain more how to i do.
i created array in top of my kendo grid
var statusLikeEntityStatus = new[]
{
new {Id = 0, Status = EntityStatus.Passive},
new {Id = 1, Status = EntityStatus.Active},
new {Id = 2, Status = EntityStatus.Draft},
new {Id = 3, Status = EntityStatus.ReadyToLive},
new {Id = -1, Status = EntityStatus.Freezed},
new {Id = -2, Status = EntityStatus.Blocked}
};
Then i use ForeignKey property instead of Bound.
columns.ForeignKey(m => m.Status, statusLikeEntityStatus, "Id", "Status").Title(Resources.General.Status);
Here is my columns attribute
.Columns(columns =>
{
columns.Bound(m => m.InventoryID).Title("Id");
columns.Bound(m => m.ERPCode).Title(Resources.Products.ProductCode);
columns.Bound(m => m.Price).Title(Resources.Products.ListPrice);
columns.Bound(m => m.Discount).Title(Resources.Products.
columns.Bound(m => m.Stock).Title(Resources.Products.TotalStock); // todo: Resources
columns.ForeignKey(m => m.Status, statusLikeEntityStatus, "Id", "Status").Title(Resources.General.Status);
columns.Command(commandConf =>
{
commandConf.Edit();
commandConf.Destroy();
});
})
Hope it will help to you.

how to get selected row value in the KendoUI

I have a kendoUI grid.
#(Html.Kendo().Grid<EntityVM>()
.Name("EntitesGrid")
.HtmlAttributes(new { style = "height:750px;width:100%;scrollbar-face-color: #eff7fc;" })
.Columns(columns =>
{
columns.Bound(e => e.Id).Hidden().IncludeInMenu(false);
columns.Bound(e => e.EntityVersionId).Hidden().IncludeInMenu(false);
columns.Bound(e => e.Name).Width("70%").Title("Entity Name");
columns.Bound(e => e.EIN).Width("30%");
})
.ToolBar(toolBar => toolBar.Template("<a class='k-button k-button-icontext k-grid-add' id='addEntity'><span class='k-icon k-add'></span>Entity</a>" +
"<a class='k-button k-button-icontext' id='editEntity'><span class='k-icon k-edit'></span>Edit</a>"))
.DataSource(dataSource => dataSource
.Ajax().ServerOperation(false)
.Model(model => model.Id(e => e.Id))
.Read(read => read.Action("GetEntities", "Entity", new { projectId = Request.QueryString[DataKeyNameConstants.ProjectId] })))
.Sortable()
.Scrollable()
.Filterable()
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.ColumnMenu()
.Selectable(s => s.Mode(GridSelectionMode.Multiple))
.Events(events => events.Change("entSelChange"))
)
now, I need to get the value of EntityVersionId from the selected Row. but not sure how to do it.
here's my javascript function
$("#editEntity").click(function () {
var entityGrid = $("#EntitesGrid").data("kendoGrid");
// what should I do from here
});
UPDATE: add code to loop all rows.
function loadPreviousEntityVersion() {
alert("sdfsdfsdf");
var entityGrid = $("#EntitesGrid").data("kendoGrid");
var data = entityGrid.dataSource.data();
for(var i = 0; i<data.length; i++) {
var currentDataItem = data[i];
alert(dataItem.EntityVersionId);
}
}
One way is to use the Grid's select() and dataItem() methods.
In single selection case, select() will return a single row which can be passed to dataItem()
var entityGrid = $("#EntitesGrid").data("kendoGrid");
var selectedItem = entityGrid.dataItem(entityGrid.select());
// selectedItem has EntityVersionId and the rest of your model
For multiple row selection select() will return an array of rows. You can then iterate through the array and the individual rows can be passed into the grid's dataItem().
var entityGrid = $("#EntitesGrid").data("kendoGrid");
var rows = entityGrid.select();
rows.each(function(index, row) {
var selectedItem = entityGrid.dataItem(row);
// selectedItem has EntityVersionId and the rest of your model
});
There is better way. I'm using it in pages where I'm using kendo angularJS directives and grids has'nt IDs...
change: function (e) {
var selectedDataItem = e != null ? e.sender.dataItem(e.sender.select()) : null;
}
I think it needs to be checked if any row is selected or not?
The below code would check it:
var entityGrid = $("#EntitesGrid").data("kendoGrid");
var selectedItem = entityGrid.dataItem(entityGrid.select());
if (selectedItem != undefined)
alert("The Row Is SELECTED");
else
alert("NO Row Is SELECTED")
If you want to select particular element use below code
var gridRowData = $("<your grid name>").data("kendoGrid");
var selectedItem = gridRowData.dataItem(gridRowData.select());
var quote = selectedItem["<column name>"];

Resources