I have a Silverlight app with Ria Service and EF. In my ViewModel i want to access a coleccion by navigating the entity relationship, in my service i have setup the query and i see that my collection is retrieved correctly, but in my Silverlight side in my ViewModel class it is lost. Anybody had come across with this issue?
The code in DomainService:
var retVal = (from e in ObjectContext.embarques.Include("Bultos")
where e.nro_embarque == nroEmbarque && e.nro_sub_embarque == nroSubembarque
select e).FirstOrDefault();
return retVal;
Above retVal have the desired result in Bultos, then in my ViewModel
EntityQuery<embarques> query = context.GetEmbarqueQuery(NroEmbarque, NroSubembarque);
LoadOperation<embarques> op = context.Load(query);
op.Completed += (sender, e) => {
if (!op.HasError) {
Embarque = op.Entities.FirstOrDefault();
if (null != Embarque) {
Bultos = new ObservableCollection<Bultos>(Embarque.Bultos);
}
}
};
}
Above Embarque.Bultos.Count = 0
The only peace i was missing here is to put [Include] attribute in embarquesMetadata class:
internal sealed class embarquesMetadata
{
...
[Include]
public EntityCollection<Bulto> Bultos{ get; set; }
...
}
once included, everything like a charm
Related
Hello I'm using Lync SDK 2013, to display number phones from contact in ListBox, and use the Items (phone number) to call this number by my API. So i did a WPF application, that contains just a ListBox, and 2 buttons (Call - Hang up). My apllication is added as custom command in Lync, in RightClick in the contact. and it doesn't have any Lync Controls. So what i want to do is: if i Right Click on the contact, my application launches and gives me the number phone List in the ListBox. I did it with a WPF that contains the controls: ContactSearchInputBox (to search a contact) and ContactSearchResultList and it works very Well, I don't know how to do it without controls.
Any One Can Help Me !!!! :(
You need to read and understand the Lync SDK 2013 Lync Contact documentation.
If you wish to "simulate" the Lync Contact "search" (as per the Client search) then you need to look into the search API.
The other concepts you need to understand is the results returned from all the API are NOT guaranteed to return all the Lync Contact data that asked for.
There is no way with the Lync SDK to "load" all the contact information which is what most people seem to not understand.
The results returned are what the local cache has and no more. To get the all the Lync Contact information you need to understand the ContactSubscription model.
For each Lync Contact that you wish to be notified of field updates (or loads) you "subscribe" to the Lync Contact and then you will be notified via the Contact.ContactInformationChanged event.
So your UI must to able to auto-update the information as the fields get loaded / updated from any initial value returned from any Lync Contact value.
public partial class ChoosePhoneNumber : Window
{
LyncClient lync_client;
Contact contact;
ContactSubscription contact_subscription;
List<ContactInformationType> contact_information_list;
ContactManager contact_manager;
public ChoosePhoneNumber()
{
InitializeComponent();
connect_lync();
get_subscribed_contact(this.contact);
}
}
private void connect_lync()
{
try
{
lync_client = LyncClient.GetClient();
contact_manager = lync_client.ContactManager;
}
catch (ClientNotFoundException)
{
MessageBox.Show("Client is ot running", "Error While GetClient", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void get_subscribed_contact(Contact contact)
{
List<object> contact_phone_numbers_list = new List<object>();
contact_information_list = new List<ContactInformationType>();
contact_information_list.Add(ContactInformationType.ContactEndpoints);
contact_information_list.Add(ContactInformationType.DisplayName);
contact = contact_manager.GetContactByUri("number"); // I put here the number phone of a contact in my list
contact_subscription = LyncClient.GetClient().ContactManager.CreateSubscription();
contact_subscription.AddContact(contact);
contact.ContactInformationChanged += Contact_ContactInformationChanged;
contact_subscription.Subscribe(ContactSubscriptionRefreshRate.High, contact_information_list);
List<object> endpoints = (List<object>)contact.GetContactInformation(ContactInformationType.ContactEndpoints);
var phone_numbers_list = endpoints.Where<object>(N => ((ContactEndpoint)N).Type == ContactEndpointType.HomePhone ||
((ContactEndpoint)N).Type == ContactEndpointType.MobilePhone || ((ContactEndpoint)N).Type == ContactEndpointType.OtherPhone
|| ((ContactEndpoint)N).Type == ContactEndpointType.WorkPhone).ToList<object>();
var name = contact.GetContactInformation(ContactInformationType.DisplayName);
if (phone_numbers_list != null)
{
foreach (var phone_number in phone_numbers_list)
{
contact_phone_numbers_list.Add(((ContactEndpoint)phone_number).DisplayName);
}
conboboxPhoneNumbers.ItemsSource = contact_phone_numbers_list;
}
}
private void Contact_ContactInformationChanged(object sender, ContactInformationChangedEventArgs e)
{
var contact = (Contact)sender;
if (e.ChangedContactInformation.Contains(ContactInformationType.ContactEndpoints))
{
update_endpoints(contact);
}
}
private void update_endpoints(Contact contact)
{
if ((lync_client != null) && (lync_client.State == ClientState.SignedIn))
{
ContactEndpoint endpoints = (ContactEndpoint)contact.GetContactInformation(ContactInformationType.ContactEndpoints);
}
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
App.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException; ;
try
{
string argsParam = "Contacts=";
if (e.Args.Length > 1)
{
if (e.Args[2].Contains(argsParam))
{
var contacts_sip_uri = e.Args[2].Split('<', '>')[1];
Params.contacts = contacts_sip_uri;
}
}
}
catch (Exception ex)
{
MessageBox.Show("Reading Startup Arguments Error - " + ex.Message);
}
}
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
string message = e.Exception.Message;
if (e.Exception.InnerException != null)
{
message += string.Format("{0}Inner Exception: {1}", Environment.NewLine, e.Exception.InnerException.Message);
}
MessageBox.Show(message, "Unhandled Exception", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
Params is a public static class that contains just contact as public static string contacts { get; set; }
public static class ParamContact
{
public static string contacts { get; set; }
}
I'm new to unit testing.Can anyone explain me about how to done unit testing without hitting Database.
And also i want to know that, Is dependency injection essential for unit testing?
If yes, explain me with a sample code. It will be helpful for me.
I had already created unit testing for login, which hits Database. But i want to test the same case for the login, without hitting database.
In this, i used Microsoft.VisualStudio.TestTools.UnitTesting.
Here is my code,
[TestMethod]
public void _01_LoginUser_01_Valid()
{
BLUser.User.UserDTO user = new BLUser.User.UserDTO();
user.UserName = "mohan";
user.UserPassword = "abc";
BLUser.Model.Fs_User result = BLUser.User.LoginUser(user);
Assert.AreEqual("mohan", result.UserName);
}
And my business logic is,
public static Fs_User LoginUser(UserDTO userDTO)
{
try
{
var context = new UserDBEntities();
{
var LoginUser = context.Fs_User.Where(u => u.UserName == userDTO.UserName && u.UserPassword == userDTO.UserPassword).SingleOrDefault();
if (LoginUser == null)
ValidationError.LoginException((int)ExceptionCodes.InvalidPassword);
return LoginUser;
}
}
catch (Exception ex)
{
throw ex;
}
}
See my answer here: Solid Principle examples anywhere?
If you look at the idea of depending on an interface for your data access, you'll see how you could supply a 'fake' implementation of that interface for testing that would not depend on a database.
Based on your example, you need to make something like the following changes:
public class LoginThing
{
private readonly IAmSomeContext context;
public LoginThing(IAmSomeContext context)
{
this.context = context;
}
public Fs_User LoginUser(UserDTO userDTO)
{
try
{
var LoginUser =
this.context.Fs_User
.SingleOrDefault(
u =>
u.UserName == userDTO.UserName
&& u.UserPassword == userDTO.UserPassword);
if (LoginUser == null)
ValidationError.LoginException((int)ExceptionCodes.InvalidPassword);
return LoginUser;
}
catch (Exception ex)
{
throw ex;
}
}
}
And then your test can become something like:
[TestMethod]
public void _01_LoginUser_01_Valid()
{
BLUser.User.UserDTO user = new BLUser.User.UserDTO();
user.UserName = "mohan";
user.UserPassword = "abc";
var fakeContext = CreateFakeContextWith(user);
var thingUnderTest = new LoginThing(fakeContext);
BLUser.Model.Fs_User result = thingUnderTest.LoginUser(user);
Assert.AreEqual("mohan", result.UserName);
}
Creating the fake context would look something like this, if you used NSubstitute:
private IAmSomeContext CreateFakeContextWith(BLUser.User.UserDTO user)
{
var fakeContext = Substitute.For<IFakeContext>();
fakeContext.Fs_User.Returns(new List(new[] {user}));
return fakeContext;
}
The syntax might not be exact, but you get the point...
In my class, I have a property for a file attachment like so...
public class Certificate {
[Required]
// TODO: Wow looks like there's a problem with using regex in MVC 4, this does not work!
[RegularExpression(#"^.*\.(xlsx|xls|XLSX|XLS)$", ErrorMessage = "Only Excel files (*.xls, *.xlsx) files are accepted")]
public string AttachmentTrace { get; set; }
}
I don't see anything wrong with my regex, but I always get ModelState.IsValid false. This seems pretty trivial and simple regex, am I missing something? Do I need to write my own custom validation?
I'm populating AttachmentTrace via a regular input of type file:
<div class="editor-label">
#Html.LabelFor(model => model.AttachmentTrace)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.AttachmentTrace, new { type = "file" })
#Html.ValidationMessageFor(model => model.AttachmentTrace)
</div>
The action method is just a regular action:
public ActionResult Create(Certificate certificate, HttpPostedFileBase attachmentTrace, HttpPostedFileBase attachmentEmail)
{
if (ModelState.IsValid)
{
// code ...
}
return View(certificate);
}
Ok, here's the solution I found. I'm sure there are other solutions out there. First a little background, because my application uses EF code-first migration, specifying a HttpPostedFileBase property type in my model, produces this error when adding migration:
One or more validation errors were detected during model generation:
System.Data.Entity.Edm.EdmEntityType: : EntityType
'HttpPostedFileBase' has no key defined. Define the key for this
EntityType. \tSystem.Data.Entity.Edm.EdmEntitySet: EntityType:
EntitySet 'HttpPostedFileBases' is based on type 'HttpPostedFileBase'
that has no keys defined.
So I really had to stick with using a string type for the AttachmentTrace property.
The solution is to employ a ViewModel class like this:
public class CertificateViewModel {
// .. other properties
[Required]
[FileTypes("xls,xlsx")]
public HttpPostedFileBase AttachmentTrace { get; set; }
}
Then create a FileTypesAttribute like so, I borrowed this code from this excellent post.
public class FileTypesAttribute : ValidationAttribute {
private readonly List<string> _types;
public FileTypesAttribute(string types) {
_types = types.Split(',').ToList();
}
public override bool IsValid(object value) {
if (value == null) return true;
var postedFile = value as HttpPostedFileBase;
var fileExt = System.IO.Path.GetExtension(postedFile.FileName).Substring(1);
return _types.Contains(fileExt, StringComparer.OrdinalIgnoreCase);
}
public override string FormatErrorMessage(string name) {
return string.Format("Invalid file type. Only {0} are supported.", String.Join(", ", _types));
}
}
In the controller Action, I needed to make a change to use the ViewModel instead, then map it back to my Entity using AutoMapper (which is excellent by the way):
public ActionResult Create(CertificateViewModel certificate, HttpPostedFileBase attachmentTrace, HttpPostedFileBase attachmentEmail) {
if (ModelState.IsValid) {
// Let's use AutoMapper to map the ViewModel back to our Certificate Entity
// We also need to create a converter for type HttpPostedFileBase -> string
Mapper.CreateMap<HttpPostedFileBase, string>().ConvertUsing(new HttpPostedFileBaseTypeConverter());
Mapper.CreateMap<CreateCertificateViewModel, Certificate>();
Certificate myCert = Mapper.Map<CreateCertificateViewModel, Certificate>(certificate);
// other code ...
}
return View(myCert);
}
For the AutoMapper, I created my own TypeConverter for the HttpPostedFileBase as follows:
public class HttpPostedFileBaseTypeConverter : ITypeConverter<HttpPostedFileBase, string> {
public string Convert(ResolutionContext context) {
var fileBase = context.SourceValue as HttpPostedFileBase;
if (fileBase != null) {
return fileBase.FileName;
}
return null;
}
}
That's it. Hope this helps out others who may have this same issue.
I don't have much experience with .NET Web Api, but i've been working with it a while now, following John Papa's SPA application tutorial on Pluralsight. The application works fine, but the thing i'm struggling with now, is unit testing POST-controllers.
I have followed this incredible guide on how to unit test web api controllers. The only problem for me is when it comes to test the POST method.
My controller looks like this:
[ActionName("course")]
public HttpResponseMessage Post(Course course)
{
if (course == null)
throw new HttpResponseException(HttpStatusCode.NotAcceptable);
try
{
Uow.Courses.Add(course);
Uow.commit();
}
catch (Exception)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
var response = Request.CreateResponse(HttpStatusCode.Created, course);
string uri = Url.Link(routeName: "ControllerActionAndId",
routeValues: new { id = course.Id });
response.Headers.Location = new Uri(uri);
return response;
}
And my unit test looks like this:
[Test]
public void PostShouldReturnHttpResponse()
{
var populatedPostController = new CoursesController(new TestUOW());
SetupPostControllerForTest(populatedPostController);
var course = new Course
{
Id = 12,
Author = new UserProfile()
{
Firstname = "John",
Lastname = "Johnson",
},
Description = "Testcourse",
Title = "Test Title"
};
var responses = populatedPostController.Post(course);
ObjectContent content = responses.Content as ObjectContent;
Course result = (Course)content.Value;
Assert.AreSame(result, course);
}
With the help function:
public static void SetupPostControllerForTest(ApiController controller)
{
var config = new HttpConfiguration();
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/courses/course");
var route = config.Routes.MapHttpRoute(
name: "ControllerActionAndId",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: null,
constraints: new { id = #"^\d+$" }
);
var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "courses" }, { "action", "course" } });
controller.ControllerContext = new HttpControllerContext(config, routeData, request);
controller.Request = request;
controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;
}
When i debug the unit test, it seems to fail at:
string uri = Url.Link(routeName: "ControllerActionAndId",
routeValues: new { id = course.Id });
response.Headers.Location = new Uri(uri); //Exception because uri = null
It seems like the Url.Link can't find the route.
I tried this guide aswell, but i really want the example i have above to work.
Am i missing something really basic here?
Yes, you are missing the one line in the configuration as Nemesv mentioned.
controller.Request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData
As you can see, configuring a controller just for using the UrlHelper is extremely complex. I tend to avoid the use of UrlHelper in the controller classes for that reason. I usually introduce an external dependency to make testing easier like an IUrlHelper, which allows me to mock the behavior in an unit test.
public interface IUrlHelper
{
string Link(string routeName, object routeValues);
string Route(string routeName, object routeValues);
}
public class UrlHelperWrapper : IUrlHelper
{
UrlHelper helper;
public UrlHelperWrapper(UrlHelper helper)
{
this.helper = helper;
}
public string Link(string routeName, object routeValues)
{
return this.helper.Link(routeName, routeValues);
}
public string Route(string routeName, object routeValues)
{
return this.helper.Route(routeName, routeValues);
}
}
I inject this UrlHelperWraper in the real Web API, and a mock of the IUrlHelper interface in the tests. By doing that, you don't need all that complex configuration with the routes.
Regards,
Pablo.
I want to create test case for below method "GetByEmail".
public User GetByEmail(string email, bool includeUserRoles = false, bool includeUserType = false)
{
Expression<Func<User>> whereClause = u => u.Email == email;
return GetQuery(whereClause, includeUserRoles, includeUserType) .FirstOrDefault();
}
private IQueryable<User> GetQuery(Expression<Func<User>> whereClause,
bool includeUserRoles = false, bool includeUserType = false)
{
IQueryable<User> query = base.GetQuery(whereClause);
if (includeUserRoles)
query = query.Include(u => u.UserRoles);
if (includeUserType)
query = query.Include(u => u.UserType);
return query;
}
protected IQueryable<T> GetQuery<T>(Expression<Func<T>> predicate) where T : EntityBase
{
return predicate != null ?
CreateObjectSet<T>().Where(predicate) :
CreateObjectSet<T>();
}
protected IObjectSet<T> CreateObjectSet<T>() where T : EntityBase
{
return _context.CreateObjectSet<T>();
}
public static IQueryable<T> Include<T>(this IQueryable<T> source, Expression<Func<T>> property)
{
var objectQuery = source as ObjectQuery<T>;
if (objectQuery != null)
{
var propertyPath = GetPropertyPath(property);
return objectQuery.Include(propertyPath);
}
return source;
}
Below is my test case method -
[Fact]
private void GetByEmail_PassedEmailAddress_RelatedUser()
{
//Created fake context
var fakeContext = Isolate.Fake.Instance<Entities>();
//Created fake Repository and passed fakeContext to it
var fakeRepository = Isolate.Fake.Instance<Repository>(Members.CallOriginal, ConstructorWillBe.Called, fakeContext);
//Created fake in memory collection of User
var fakeUsers = GetUsers();
Isolate.WhenCalled(() => fakeContext.Context.CreateObjectSet<User>())
.WillReturnCollectionValuesOf(fakeUsers);
var User = Isolate.Invoke.Method(fakeRepository, "GetByEmail", "abc#xyz.com", true, true);
Assert.True(User != null);
}
In the above test case method I successfully get the user with passed email but not able to include other entities of associated user.
Kindly let me know, how can I include other entities with associated User.
Include is leaky abstraction - it works only with EF and linq-to-entities and cannot be successfully used with linq-to-objects. You know that your unit test needs populated relations so your GetUsers method must prepare that data. That is a point of mocking / faking - you don't think about internal implementation of mocked method. You simply return what should be returned.
Btw. what is the point of your test? It looks like you are trying to test a mock - that is wrong. Mock provides correct data and you only need it to test another feature dependent on mocked component.