I am trying to unit test validations on a object with a base class. I am expecting 3 properties (Email,Phone and Skill>0) to fail validation, but the test is failing.
BASE CLASS
public abstract class Person : Entity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } }
public string Email { get; set; }
public string Phone { get; set; }
public DateTime DateAdded { get; set; }
public bool Active { get; set; }
}
DERIVED CLASS
public class Contractor : Person, IValidatableObject
{
public Address Address { get; set; }
public List<Skill> SkillSet { get; set; }
public DateTime? NextAvailableDate { get; set; }
public Contractor()
{
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (string.IsNullOrWhiteSpace(base.FirstName))
yield return new ValidationResult("The First Name field cannot be empty.");
if (string.IsNullOrWhiteSpace(base.LastName))
yield return new ValidationResult("The Last Name field cannot be empty.");
if (string.IsNullOrWhiteSpace(base.Email))
yield return new ValidationResult("The Email field cannot be empty.");
if (string.IsNullOrWhiteSpace(base.Phone))
yield return new ValidationResult("The Phone field cannot be empty.");
if (SkillSet.Count() < 1)
yield return new ValidationResult("A contractor must have at least one skill.");
}
TEST
[TestMethod]
public void contractor_is_missing_email_phone_skill_when_created()
{
//Arrange
Contractor contractor = new Contractor { FirstName = "abc", LastName = "def" };
//Act
ValidationContext context = new ValidationContext(contractor);
IEnumerable<ValidationResult> result = contractor.Validate(new ValidationContext(contractor));
List<ValidationResult> r = new List<ValidationResult>(result);
//Assert
Assert.IsTrue(r.Count == 3);
}
Initialise your list when you create a new contractor.
public Contractor()
{
SkillSet = new List<Skill>();
}
Related
I have added model validator to validate to model. it's covered only required fields but not others.
public static class TestModelHelper
{
public static IList<ValidationResult> Validate(object model)
{
var results = new List<ValidationResult>();
var validationContext = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, validationContext, results, true);
if (model is IValidatableObject)
{
(model as IValidatableObject).Validate(validationContext);
}
return results;
}
}
public class Employee
{
[Key]
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[Required]
[JsonProperty("emailId")]
public string EmailId { get; set; }
}
using below command to generate the code coverage report.
dotnet test --collect:"XPlat Code Coverageā
reportgenerator "-reports:./TestResults/{testresultsId}/coverage.cobertura.xml" "-targetdir:coveragereport" "-"reporttypes:Html"
in this model emailId only covered in code coverage. id and name are not covered.
According to your codes, I don't found any validate attribute for the Name and Id, if you want to test validate result, you should put some validate attributes for them.
More details, you could refer to below codes and try again.
public class Employee
{
[JsonProperty("id")]
[Range(0, 999.99)]
public int Id { get; set; }
[StringLength(100)]
[JsonProperty("name")]
public string Name { get; set; }
[Required]
[JsonProperty("emailId")]
public string EmailId { get; set; }
}
I am writing a Provider Hosted APP using SP 2013 and I have a data layer which uses REST to CRUD on sharepoint lists. Now I got the List items in JSON format but I am not able to iterate through the list data can you please help in doing that? (is there any class for List Items which I can deserialize into?)
This is the code
public JToken GetListData(string webUrl, string userName, SecureString password, string listTitle)
{
using (var client = new WebClient())
{
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
client.Credentials = new SharePointOnlineCredentials(userName, password);
client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
var endpointUri = new Uri(new Uri(webUrl), string.Format("/sites/DTF/_api/web/lists/getbytitle('{0}')/Items", listTitle));
var result = client.DownloadString(endpointUri);
var t = JToken.Parse(result);
return t["d"];
}
}
You need to use the DataContractJsonSerializer class to deserialize the data as is demonstrated here:
http://www.codeproject.com/Articles/272335/JSON-Serialization-and-Deserialization-in-ASP-NET
To make this work though you have to create classes that match the structure of the Json. The easiest way to do this copying a raw Json response into a tool which will generate the classes like this one:
http://json2csharp.com/
The actual classes you will need to generate varies based on the structure of the data you are getting in your REST response. Here is an example I created that demonstrates making a request, parsing the Json Response and downloading a file based on the result:
public class JsonHelper
{
/// JSON Serialization
public static string JsonSerializer<T>(T t)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, t);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return jsonString;
}
/// JSON Deserialization
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
}
//Custom Json Classes
public class RootObject
{
public D d { get; set; }
}
public class D
{
public GetContextWebInformation GetContextWebInformation { get; set; }
public List<Result> results { get; set; }
}
public class GetContextWebInformation
{
public int FormDigestTimeoutSeconds { get; set; }
public string FormDigestValue { get; set; }
public string LibraryVersion { get; set; }
public string SiteFullUrl { get; set; }
public string WebFullUrl { get; set; }
}
public class Result
{
public ContentType ContentType { get; set; }
public string EncodedAbsUrl { get; set; }
public string FileLeafRef { get; set; }
public Folder Folder { get; set; }
public int FileSystemObjectType { get; set; }
public int Id { get; set; }
public string ContentTypeId { get; set; }
public string Title { get; set; }
public int? ImageWidth { get; set; }
public int? ImageHeight { get; set; }
public string ImageCreateDate { get; set; }
public object Description { get; set; }
public object Keywords { get; set; }
public string OData__dlc_DocId { get; set; }
public int ID { get; set; }
public string Created { get; set; }
public int AuthorId { get; set; }
public string Modified { get; set; }
public int EditorId { get; set; }
public object OData__CopySource { get; set; }
public int? CheckoutUserId { get; set; }
public string OData__UIVersionString { get; set; }
public string GUID { get; set; }
}
//SharePoint Calls
class Program
{
static void Main()
{
string url = "https://sharepoint.wilsonconst.com/";
string filename = "2010-07-23 13.32.22.jpg";
string digest = "";
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
string cmd = "_api/contextinfo";
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json");
client.DefaultRequestHeaders.Add("ContentLength", "0");
StringContent httpContent = new StringContent("");
HttpResponseMessage response = client.PostAsync(cmd, httpContent).Result;
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
RootObject sp = JsonHelper.JsonDeserialize<RootObject>(content);
digest = sp.d.GetContextWebInformation.FormDigestValue;
}
client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-RequestDigest", digest);
client.DefaultRequestHeaders.Add("X-HTTP-Method", "GET");
string uri = "_api/web/lists/GetByTitle('Wilson Pictures')/Items?$select=ID,FileLeafRef,EncodedAbsUrl&$filter=FileLeafRef eq '" + filename + "'";
HttpResponseMessage response2 = client.GetAsync(uri).Result;
response2.EnsureSuccessStatusCode();
if (response2.IsSuccessStatusCode)
{
string listItems = response2.Content.ReadAsStringAsync().Result;
RootObject sp = JsonHelper.JsonDeserialize<RootObject>(listItems);
foreach (Result result in sp.d.results)
{
MemoryStream stream = (MemoryStream)client.GetAsync(result.EncodedAbsUrl).Result.Content.ReadAsStreamAsync().Result;
using(FileStream fileStream = System.IO.File.Create(#"C:\" + result.FileLeafRef))
{
stream.WriteTo(fileStream);
}
}
}
else
{
var content = response.Content.ReadAsStringAsync();
}
}
This seems like a lot of complexity, but really it makes working with Json objects quite easy and takes only moments to setup before you can start calling your custom objects to easily manipulate the data.
Assuming that you want to retrieve data from SharePoint Online the following example demonstrates how to consume SharePoint REST Interface via WebClient Class:
using (var client = new SPRestClient(webUri.ToString()))
{
client.Credentials = GetCredentials(webUri,userName,password);
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
var data = client.GetJson("/_api/lists/getbytitle('Tasks')/items"); //get list items
//print list item's title
foreach (var item in data["d"]["results"])
{
Console.WriteLine(item["Title"]);
}
}
where
public static SharePointOnlineCredentials GetCredentials(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var ch in password) securePassword.AppendChar(ch);
return new SharePointOnlineCredentials(userName, securePassword);
}
and
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace SharePoint.Client
{
public class SPRestClient : WebClient
{
public SPRestClient(string webUri)
{
BaseAddress = webUri;
FormatType = JsonFormatType.Verbose;
}
public JObject GetJson(string requestUri)
{
return ExecuteJson(requestUri, HttpMethod.Get, null, default(string));
}
public JObject ExecuteJson<T>(string requestUri, HttpMethod method, IDictionary<string, string> headers, T data)
{
string result;
var uri = BaseAddress + requestUri;
if (headers != null)
{
foreach (var key in headers.Keys)
{
Headers.Add(key, headers[key]);
}
}
EnsureRequest(method);
switch (method.Method)
{
case "GET":
result = DownloadString(uri);
break;
case "POST":
if (data != null)
{
var payload = JsonConvert.SerializeObject(data);
result = UploadString(uri, method.Method, payload);
}
else
{
result = UploadString(uri, method.Method);
}
break;
default:
throw new NotSupportedException(string.Format("Method {0} is not supported", method.Method));
}
return JObject.Parse(result);
}
private void EnsureRequest(HttpMethod method)
{
var mapping = new Dictionary<JsonFormatType, string>();
mapping[JsonFormatType.Verbose] = "application/json;odata=verbose";
mapping[JsonFormatType.MinimalMetadata] = "application/json; odata=minimalmetadata";
mapping[JsonFormatType.NoMetadata] = "application/json; odata=nometadata";
Headers.Add(HttpRequestHeader.ContentType, mapping[FormatType]);
Headers.Add(HttpRequestHeader.Accept, mapping[FormatType]);
if (method == HttpMethod.Post)
{
Headers.Add("X-RequestDigest", RequestFormDigest());
}
}
private string RequestFormDigest()
{
var endpointUrl = string.Format("{0}/_api/contextinfo", BaseAddress);
var result = UploadString(endpointUrl, "Post");
var contentJson = JObject.Parse(result);
return contentJson["FormDigestValue"].ToString();
}
public JsonFormatType FormatType { get; set; }
}
public enum JsonFormatType
{
Verbose,
MinimalMetadata,
NoMetadata
}
}
SPRestClient.cs
I want to manage users and Roles in the cliente side, but i cannot find the way to accomplish this. Links or code will be very appreciated.
Sorry for this abandoned question, i have solved this issue many days ago now, and i fill i should post the answer here because i couldnt find a complete answer in the web and this can help some soul in distress over there. Except for a link that i cannot remember right now but,my apologise to the blog owner for not remember even his name, however, here is the full history:
First create a class to wrap MembershipUser and another one to wrap MembsershipRole:
public class MembershipServiceUser
{
public string Comment { get; set; }
[Editable(false)]
public DateTime CreationDate { get; set; }
[Key]
[Editable(false, AllowInitialValue = true)]
public string Email { get; set; }
public bool IsApproved { get; set; }
[Editable(false)]
public bool IsLockedOut { get; set; }
[Editable(false)]
public bool IsOnline { get; set; }
public DateTime LastActivityDate { get; set; }
[Editable(false)]
public DateTime LastLockoutDate { get; set; }
public DateTime LastLoginDate { get; set; }
[Editable(false)]
public DateTime LastPasswordChangedDate { get; set; }
[Editable(false)]
public string PasswordQuestion { get; set; }
[Key]
[Editable(false, AllowInitialValue = true)]
public string UserName { get; set; }
public MembershipServiceUser() { }
public MembershipServiceUser(MembershipUser user)
{
this.FromMembershipUser(user);
}
public void FromMembershipUser(MembershipUser user)
{
this.Comment = user.Comment;
this.CreationDate = user.CreationDate;
this.Email = user.Email;
this.IsApproved = user.IsApproved;
this.IsLockedOut = user.IsLockedOut;
this.IsOnline = user.IsOnline;
this.LastActivityDate = user.LastActivityDate;
this.LastLockoutDate = user.LastLockoutDate;
this.LastLoginDate = user.LastLoginDate;
this.LastPasswordChangedDate = user.LastPasswordChangedDate;
this.PasswordQuestion = user.PasswordQuestion;
this.UserName = user.UserName;
}
public MembershipUser ToMembershipUser()
{
MembershipUser user = Membership.GetUser(this.UserName);
if (user.Comment != this.Comment) user.Comment = this.Comment;
if (user.IsApproved != this.IsApproved) user.IsApproved = this.IsApproved;
if (user.LastActivityDate != this.LastActivityDate) user.LastActivityDate = this.LastActivityDate;
if (user.LastLoginDate != this.LastLoginDate) user.LastLoginDate = this.LastLoginDate;
return user;
}
}
//Roles
public class MembershipServiceRole {
public MembershipServiceRole() { }
public MembershipServiceRole(string rolename) {
RoleName = rolename;
}
[Key]
[Editable(true, AllowInitialValue = true)]
public string RoleName { get; set; }
}
Second, create a class derived from DomainService to manipulate users and roles wrappers:
[EnableClientAccess(RequiresSecureEndpoint = false /* This should be set to true before the application is deployed */)]
public class MembershipService : DomainService
{
protected override void OnError(DomainServiceErrorInfo errorInfo)
{
TimeoutHelper.HandleAuthenticationTimeout(errorInfo, this.ServiceContext.User);
}
[RequiresRole("Administrator")]
public IEnumerable<MembershipServiceUser> GetUsers()
{
return Membership.GetAllUsers().Cast<MembershipUser>().Select(u => new MembershipServiceUser(u));
}
[RequiresRole("Administrator")]
public IEnumerable<MembershipServiceUser> GetUsersByEmail(string email)
{
return Membership.FindUsersByEmail(email).Cast<MembershipUser>().Select(u => new MembershipServiceUser(u));
}
[RequiresRole("Administrator")]
public MembershipServiceUser GetUsersByName(string userName)
{
MembershipServiceUser retVal = null;
retVal = Membership.FindUsersByName(userName)
.Cast<MembershipUser>()
.Select(u => new MembershipServiceUser(u))
.FirstOrDefault();
return retVal;
}
[Invoke(HasSideEffects = true)]
public void CreateUser(MembershipServiceUser user, string password)
{
if (string.IsNullOrEmpty(user.Email)) {
user.Email = "cambiar#dominio.com";
}
Membership.CreateUser(user.UserName, password, user.Email);
}
[RequiresRole("Administrator")]
public void DeleteUser(MembershipServiceUser user)
{
Membership.DeleteUser(user.UserName);
}
[RequiresRole("Administrator")]
public void UpdateUser(MembershipServiceUser user)
{
Membership.UpdateUser(user.ToMembershipUser());
}
[RequiresRole("Administrator")]
[Update(UsingCustomMethod = true)]
public void ChangePassword(MembershipServiceUser user, string newPassword)
{
MembershipUser u = user.ToMembershipUser();
u.ChangePassword(u.ResetPassword(), newPassword);
}
[RequiresRole("Administrator")]
public void ResetPassword(MembershipServiceUser user)
{
user.ToMembershipUser().ResetPassword();
}
[RequiresRole("Administrator")]
public void UnlockUser(MembershipServiceUser user)
{
user.ToMembershipUser().UnlockUser();
}
#region Roles
[RequiresRole("Administrator")]
public IEnumerable<MembershipServiceRole> GetRoles() {
return Roles.GetAllRoles().Cast<string>().Select(r => new MembershipServiceRole(r));
}
[RequiresRole("Administrator")]
public IEnumerable<MembershipServiceRole> GetRolesForUser(string userName) {
return Roles.GetRolesForUser(userName).Cast<string>().Select(r => new MembershipServiceRole(r));
}
[RequiresRole("Administrator")]
public void CreateRole(MembershipServiceRole role) {
Roles.CreateRole(role.RoleName);
}
[RequiresRole("Administrator")]
public void DeleteRole(MembershipServiceRole role) {
Roles.DeleteRole(role.RoleName);
}
[RequiresRole("Administrator")][Invoke]
public void AddUserToRole(string userName, string roleName) {
if (!Roles.IsUserInRole(userName,roleName))
Roles.AddUserToRole(userName, roleName);
}
[RequiresRole("Administrator")]
[Invoke]
public void RemoveUserFromRole(string userName, string roleName) {
if (Roles.IsUserInRole(userName, roleName))
Roles.RemoveUserFromRole(userName, roleName);
}
#endregion //Roles
}
Third: Use the service the same way you do for your domains clases
Cheers!!!
I've the following Entity Framework entities:
public class Country
{
public long Id { get; set; }
public string Code { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
public class Person
{
public long Id { get; set; }
public long? Country_Id { get; set; }
public Country HomeCountry { get; set; }
}
Moles has generated MPerson and MCountry stub classes.
Now I do want to stub the set of the Country_Id:
MPerson.AllInstances.Country_IdSetNullableOfInt64 = (Person instance, long? id) =>
{
// Do something
// Set the Country_Id to the provided id
// This will trigger this same method again and again. How to avoid this ?
instance.Country_Id = id;
};
This post gives the answer:
MolesContext.ExecuteWithoutMoles(() => instance.Country_Id = id);
I am running on Castle's trunk, and trying to unit-test a controller-action where validation of my DTO is set up. The controller inherits from SmartDispatcherController. The action and DTO look like:
[AccessibleThrough(Verb.Post)]
public void Register([DataBind(KeyReg, Validate = true)] UserRegisterDto dto)
{
CancelView();
if (HasValidationError(dto))
{
Flash[KeyReg] = dto;
Errors = GetErrorSummary(dto);
RedirectToAction(KeyIndex);
}
else
{
var user = new User { Email = dto.Email };
// TODO: Need to associate User with an Owning Account
membership.AddUser(user, dto.Password);
RedirectToAction(KeyIndex);
}
}
public class UserRegisterDto
{
[ValidateNonEmpty]
[ValidateLength(1, 100)]
[ValidateEmail]
public string Email { get; set; }
[ValidateSameAs("Email")]
public string EmailConfirm { get; set; }
[ValidateNonEmpty]
public string Password { get; set; }
[ValidateSameAs("Password")]
public string PasswordConfirm { get; set; }
// TODO: validate is not empty Guid
[ValidateNonEmpty]
public string OwningAccountIdString { get; set; }
public Guid OwningAccountId
{
get { return new Guid(OwningAccountIdString); }
}
[ValidateLength(0, 40)]
public string FirstName { get; set; }
[ValidateLength(0, 60)]
public string LastName { get; set; }
}
The unit test looks like:
[Fact]
public void Register_ShouldPreventInValidRequest()
{
PrepareController(home, ThorController.KeyPublic, ThorController.KeyHome, HomeController.KeyRegister);
var dto = new UserRegisterDto { Email = "ff" };
home.Register(dto);
Assert.True(Response.WasRedirected);
Assert.Contains("/public/home/index", Response.RedirectedTo);
Assert.NotNull(home.Errors);
}
("home" is my HomeController instance in the test; home.Errors holds a reference to an ErrorSummary which should be put into the Flash when there's a validation error).
I am seeing the debugger think that dto has no validation error; it clearly should have several failures, the way the test runs.
I have read Joey's blog post on this, but it looks like the Castle trunk has moved on since this was written. Can someone shed some light, please?
http://www.candland.net/blog/2008/07/09/WhatsNeededForCastleValidationToWork.aspx would appear to contain an answer.