mvc: same query for different repositories? - repository-pattern

My friends, you always help me in any bad situations :) Thank you.
I have 2 or more repositories working in their own contexts which return data joining to the same base query:
public IQueryable<LQ_Group> GetAdminedGroupsQ(User user)
{
try
{
return
(from ap in context.LQ_Permissions
join g in context.LQ_Groups on
new { GroupID = ap.ObjectID, GroupTypeID = ap.ObjectTypeID }
equals
new { GroupID = g.GroupID, GroupTypeID = Dict.ObjectType[ObjectType.Group].ID }
where ((ap.SubjectID == user.ID) && (ap.SubjectTypeID == Dict.ObjectType[ObjectType.User].ID))
select g);
}
catch (Exception ex)
{
throw new UnknownRepositoryException(ex.Message);
}
}
This result is used by User, Group, GroupMember and others reposotories.
What is the best way to implement that? I dont like idea to have different copies of the same logic. Thoughts?
Thank you.

You could do something like this:
public class MyRepository
{
private List<Item> mItems;
public IEnumerable<Item> GetAllItems()
{
return this.mItems;
}
public IEnumerable<Item> GetGoodItems()
{
return this.GetAllItems().Where(x => x.IsGood == true);
}
public IEnumerable<Item> GetGoodItemsOverFiveDollars()
{
return this.GetGoodItems().Where(x => x.Price > 5.00m);
}
}
public class Item
{
public bool IsGood { get; set; }
public decimal Price { get; set; }
}
You can do this because the query is not executed until the enumeration is evaluated. However, keep in mind that additional linq statements can be added outside the MyRepository class, and thus you can have "linq injection" ;).
You could avoid this by wrapping the methods and making them internal, where your wrapping methods call ToList or ToArray, allowing the query to execute.
How are you currently executing your queries, and what repetition are you trying to reduce? Can you provide an example?

Related

Unit test using dependency injection and mock objects without hitting Database

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...

readable substitution of IEnumerable of Interfaces

I have the following interfaces
public interface IRibbonCommandsProvider
{
IEnumerable<IRibbonCommand> GetRibbonCommands();
}
public interface IRibbonCommand
{
string Group { get; }
string Tab { get; }
string Name { get; }
string Image { get; }
void Execute();
}
And the follwing substitution code:
public class TabsViewModelTests
{
[Fact]
public void Initialize_BuildsCorrectRibbonTree()
{
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(
new[]
{
new RibbonCommand { Tab = "Tab1", Group = "Group1", Name = "Name1" },
new RibbonCommand { Tab = "Tab1", Group = "Group1", Name = "Name2" },
new RibbonCommand { Tab = "Tab2", Group = "Group1", Name = "Name3" },
new RibbonCommand { Tab = "Tab2", Group = "Group2", Name = "Name3" }
});
...
}
private class RibbonCommand : IRibbonCommand
{
public string Group { get; set; }
public string Tab { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public void Execute() {}
}
}
Using NSubstitute, is there a clever way to get rid of the stub RibbonCommand class (that is nothing but a fake IRibbonCommand implementation - and that's NSubstitute's job) and still have list of fake ribbon commands that is as easily readable as the above?.
I can't come up with a readable way using NSubsitute's .Returns() fluent method without ending with a lot more (and unreadable) code.
Update:
A cool NSubstitute extension method could look like this. I just don't know if and how this can be built:
public static ConfiguredCall ReturnsMany<T>(
this IEnumerable<T> value,
Action<T> configureThis,
params Action<T>[] configureThese)
{
...
}
It would be used like this:
commands.GetRibbonCommands().ReturnsMany(
subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name1");
},
subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name2");
},
subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name3");
},
subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name3");
});
I think what you've got is very good — quite succinct and clear.
If you really want to get rid of the class you can use a substitute creation method for IRibbonCommand:
private IRibbonCommand Create(string tab, string group, string name)
{
var cmd = Substitute.For<IRibbonCommand>();
cmd.Tab.Returns(tab);
cmd.Group.Returns(group);
cmd.Name.Returns(name);
return cmd;
}
[Fact]
public void Initialize_BuildsCorrectRibbonTree()
{
var ribbonCommands = new[] {
Create("tab1", "group1", "name1"),
Create("tab1", "group1", "name2"),
Create("tab2", "group1", "name3"),
Create("tab2", "group1", "name4")
};
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(ribbonCommands);
// ...
}
This doesn't buy you much, although it does mean your test code will be more protected from changes to the IRibbonCommand interface (e.g. an additional property will not require changing your test code), and means you can check received calls and stub other calls on individual items.
Aside: Can use argument names if you want to more closely match the original code:
Create(tab: "tab1", group: "group1", name: "name1"),
As alternative you may setup Command inside test. Then move config func out of the test and optionally generalize for other types as you go. Yagni it.
UPDATED to working test
[Test]
public void Test()
{
Func<Action<IRibbonCommand>, IRibbonCommand> cmd = config =>
{
var c = Substitute.For<IRibbonCommand>();
config(c);
return c;
};
var ribbonCommands = new[]
{
cmd(c => { c.Tab.Returns("Tab1"); c.Group.Returns("Group1"); c.Name.Returns("Name1"); }),
cmd(c => { c.Tab.Returns("Tab1"); c.Group.Returns("Group1"); c.Name.Returns("Name2"); }),
cmd(c => { c.Tab.Returns("Tab2"); c.Group.Returns("Group1"); c.Name.Returns("Name3"); }),
cmd(c => { c.Tab.Returns("Tab2"); c.Group.Returns("Group1"); c.Name.Returns("Name4"); })
};
var commandsProvider = Substitute.For<IRibbonCommandsProvider>();
commandsProvider.GetRibbonCommands().Returns(ribbonCommands);
}
I don't see anything out of the box that's going to do what you're after. One option might be for you to write your own extension method to make the construction easier. So, something like this:
public static class ReadOnlySubstitute {
static public T For<T>(object source) where T : class {
var sub = Substitute.For<T>();
foreach (var prop in source.GetType().GetProperties()) {
sub.GetType().GetProperty(prop.Name).GetValue(sub).Returns(prop.GetValue(source));
}
return sub;
}
}
The above code essentially creates a substitute for the given interface and then sets up a return on each of properties specified in the supplied object.
This could then be used in your test like this to supply anonymous objects with the parameters:
[Test]
public void Initialize_BuildsCorrectRibbonTree() {
var ribbonCommands = new[]
{
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab1", Group="Grp1", Name="Nam1"}),
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab1", Group="Grp1", Name="Nam2"}),
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab2", Group="Grp1", Name="Nam3"}),
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab2", Group="Grp2", Name="Nam3"})
};
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(ribbonCommands);
....
}
It's not quite as concise as using the RibbonCommand class, since you have to construct the array before passing it into the Returns method because NSubstitute gets confused if you try to setup the Returns on the elements at the same time as on the GetRibbonCommands, but I think it's fairly close.
This is really an enhancement (subjective) of #dadhi's answer, combined with an answer from #David Tchepak to a different question.
So, rather than having to create a new Func for each interface your want to use, as described by #dadhi, you can instead create a generic method that takes an Action. You could be this in a shared class, something like this:
static class ConfiguredSub {
public static T For<T>(Action<T> config) where T : class {
var c = Substitute.For<T>();
config(c);
return c;
}
}
The problem that I encountered with my other answer was that if you have nested Returns, NSubstitute gets confused and starts throwing exceptions. It turns out that as described by #David here, you can pass a Func to defer the execution and get round this issue. If you combine these two things, then you get something pretty close to what you're after.
[Test]
public void Initialize_BuildsCorrectRibbonTree() {
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(x => new[] {
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name1");
}),
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name2");
}),
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name3");
}),
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name4");
})
});
// ...
}

ModelState.IsValid is always false for RegularExpression ValidationAttribute in MVC 4

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.

Equivalent of JustMock's ReturnsCollection() in FakeItEasy?

With JustMock I can mock DataContext tables with lists in Linq to SQL easily like this, where an IEnumerable is taking the place of each DataContext's table through ReturnsCollection() allowing me to plug in fake data:
[TestMethod]
public void ShouldGetManagersByHireDate()
{
var context = Mock.Create<MyDataContext>();
Mock.Arrange(()=> context.Employees).ReturnsCollection(GetFakeEmployees());
Mock.Arrange(() => context.Managers).ReturnsCollection(GetFakeManagers());
var repository = new EmployeeRepository(context);
var managers = repository.GetManagersByHireDate(new DateTime(2002, 1, 1), DateTime.Now);
Assert.AreEqual(1, managers.Count());
Assert.AreEqual(1, managers.FirstOrDefault().ID);
}
private IEnumerable<Employee> GetFakeEmployees()
{
return new List<Employee> {
new Employee { ID = 1, HireDate = new DateTime(2004, 12, 1) },
new Employee { ID = 2, HireDate = new DateTime(2006, 7, 1) },
new Employee { ID = 3, HireDate = new DateTime(2009, 3, 1) }
};
}
private IEnumerable<Manager> GetFakeManagers()
{
return new List<Manager> {
new Manager { ID = 1 }
};
}
And this would be the method under test:
public IQueryable<Employee> GetManagersByHireDate(DateTime start, DateTime end)
{
return from e in context.Employees
join m in context.Managers on e.ID equals m.ID
where e.HireDate >= start && e.HireDate <= end
select e;
}
I am looking for some way of performing the same magic allowing me to use IEnumerable<T> in place of Table<T> for the purpose of testing Linq to SQL, preferably in FakeItEasy.
Linq to SQL isn't the easiest thing to test using open source tools. Hopefully, this approach may work for you.
FakeItEasy doesn't have a method exactly like JustMock's ReturnCollection that would allow you to mock out an ITable to return an IEnumerable. One option you have is to create a MockableTable similar to the one shown here. Then to populate your Table, you could have something like
private ITable<Employee> GetFakeEmployees() {
List<Employee> sampleData = /* fill it up with employees */
var employeeTable = new MockableTable<Employee>(null, sampleData.AsQuerable());
return employeeTable;
}
Also, FakeItEasy won't intercept the Employees property on the DataContext since it's a non virtual property on a concrete class. You could create a simple custom base class and have MyDataContext class derive directly from that.
public abstract class CustomDataContext : DataContext, ICustomDataContext {
}
public interface ICustomDataContext {
ITable<Employee> { get; }
}
The main point here is to leverage the interface for your mock. Then in your test method, you would have:
[TestMethod]
public void ShouldGetManagersByHireDate() {
var context = A.Fake<ICustomDataContext>();
A.CallTo(()=> context.Employees).Returns(GetFakeEmployees());
var repository = new EmployeeRepository(context);
var managers = repository.GetManagersByHireDate(new DateTime(2002, 1, 1), DateTime.Now);
Assert.AreEqual(1, managers.Count());
Assert.AreEqual(1, managers.FirstOrDefault().ID);
}
I haven't actually compiled this, but concept should be stable. Relying on the abstractions will make your code more testable and easier to mock.
Hope this helps somewhat.
The way I have done this using FakeItEasy is to add an interface to DataContext and use that as my dependency in my repos. E.g.
public interface IMyDataContext : IDisposable
{
IQueryable<Employee> Employees { get; }
// etc.
}
public partial class MyDataContext: IMyDataContext
{
IQueryable<Message> IMyDataContext.Employees
{
get { return this.Employees; }
}
// etc.
}
public class EmployeeRepository
{
public EmployeeRepository(IMyDataContext context)
{
// etc.
}
}
And in my test:
var context = A.Fake<IMyDataContext>();
A.CallTo(() => context.Employees).Returns(new[] { new Employee { Name = "John", Name = "Fred" }.AsQueryable());
var repository = new EmployeeRepository(context)
I don't think any considerations surrounding ITable are required.

How to map and test a "Many to Many Relationship" in NHibernate using Fluent NHibernate

When I test my many to many classes an error occurs:
System.ApplicationException: Actual
count does not equal expected count.
Entities:
public interface IEntity
{
int Id { get; set; }
}
public abstract class Entity : IEntity
{
public virtual int Id { get; set; }
public virtual bool IsPersistent
{
get { return isPersistentObject(); }
}
public override bool Equals(object obj)
{
if (isPersistentObject())
{
var persistentObject = obj as Entity;
return (persistentObject != null) && (Id == persistentObject.Id);
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return isPersistentObject() ? Id.GetHashCode() : base.GetHashCode();
}
private bool isPersistentObject()
{
return (Id != 0);
}
}
public class Team : Entity
{
public virtual string Name { get; set; }
public virtual ISet<Employee> Employees { get; set; }
public Team()
{
Employees = new HashedSet<Employee>();
}
}
public class Employee : Entity
{
public virtual string LastName { get; set; }
public virtual string FirstName { get; set; }
public virtual ISet<Team> Teams { get; set; }
public virtual string EMail { get; set; }
public Employee()
{
Teams = new HashedSet<Team>();
}
}
Mappings:
public class TeamMap : ClassMap<Team>
{
public TeamMap()
{
// identity mapping
Id(p => p.Id).Column("TeamID");
// column mapping
Map(p => p.Name);
// relationship mapping
HasManyToMany(m => m.Employees)
.Table("EmployeeTeam")
.LazyLoad()
.Cascade.SaveUpdate()
.AsSet()
.ParentKeyColumn("TeamID")
.ChildKeyColumn("EmployeeID");
}
}
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
// identifier mapping
Id(p => p.Id).Column("EmployeeID");
// column mapping
Map(p => p.EMail);
Map(p => p.LastName);
Map(p => p.FirstName);
// relationship mapping
HasManyToMany(m => m.Teams).Table("EmployeeTeam")
.Inverse()
.Cascade.SaveUpdate()
.AsSet()
.LazyLoad()
.ParentKeyColumn("EmployeeID")
.ChildKeyColumn("TeamID");
}
}
Test:
[TestMethod]
public void CanCorrectlyMapEmployee()
{
var team = new List<Team> {new Team() {Name = "Team1"}};
new PersistenceSpecification<Employee>(_session)
.CheckProperty(p => p.EMail, "Mail")
.CheckProperty(p => p.FirstName, "Firstname")
.CheckProperty(p => p.Id, 1)
.CheckProperty(p => p.LastName, "Lastname")
.CheckList(p => p.Teams,team )
.VerifyTheMappings();
}
Whether I add an Employee or a Team my EmployeeTeam table is always empty.
I have tested it against SQLLite with FNH and manually against SQL Server 2008.
Does anybody of you have an idea to fix this?
edit:
I was amazed to find out that when I create an Employee and add 2 Teams to the Employee and load the created Employee he has 2 Teams. So it works fine. But when I look in my relationsip table EmployeeTeam then everything is empty. Can someone explain me why?
And does anybody know how I can use Fluent NHibernate to test my many to many relationship?
Thanks in advance!
Employee map has inverse attribute. As you probably know, this means that when you save employee, relationship table (EmployeeTeam) will not be updated. To add/remove new relationship information you have to add employee to the Team and save Team.
So, in your case - don't test many to many on the side of employee, test it on the side of team. (If you'd like NHibernate to add records when you add team to employee, you'll have to invert "Inverse" attributes - give it to team, not employee, but then - same story with Team entity).
Why were you able to load Employee with teams? Because of session-level cache. You've probably saved and loaded Employee in the same ISession - this means that NHibernate returned you exactly reference to the same object, without loading it from the db. Try saving & loading in two different sessions and you'll see no team in Employee.Teams set.
Side note: It is considered a good practice to create methods that will enforce consistency between many-to-many relationships, that is - when you add Team to Employee, Employee is added to the team, sth. like this:
class Employee
{
// ...
public void AddTeam(Team team)
{
// check for null, etc.
Teams.Add(team);
team.Employees.Add(this);
}
}
and very simillar method in the Team class.