Need to Stub a Function that takes a Func<> as a Parameter - rhino-mocks

I have a method on my data access layer that can take any function as search criteria and run this against our Entity Framework entities. I am trying to create unit tests using Rhino Mocks on the business layer, but this calls the DAL method. When I try to create a stub for this search method, I cannot seem to get it to run correctly. I have the following method that needs to be stubbed:
IQueryable<T> AllSearchBy<T>(params Expression<Func<T, bool>>[] search) where T : class;
I cannot seem to find a generic expression to use such as Arg.Is.Anything for functions, so I tried setting up my own. I have the following that should return the first value in my _fakeObjs if the Id is 1 and should return a null if the Id is 0 (two separate tests):
myObjId = 1; // or 0 for returning a null
System.Linq.Expressions.Expression<Func<MyObj, bool>> myFunc = (a => a.Id == objId);
IRepository repositoryMock = MockRepository.GenerateMock<IRepository>();
repositoryMock.Stub(x => x.AllSearchBy<MyObj>(myFunc)).Return(_fakeObjs.Where(x => x.Id == myObjId));
However, I am getting the following errors. For the one that should return an object (value = 1):
Message: Test method
NS.MyApp.Test.ObjTest.SearchById_ReturnsObj threw exception:
System.ArgumentNullException: Value cannot be null.
Parameter name: source
For the one that should return a null (value = 0):
Message: Test method
NS.MyApp.Test.ObjTest.SearchById_ReturnsNull threw exception:
Rhino.Mocks.Exceptions.ExpectationViolationException:
IRepository.AllSearchBy<NS.EF.MyObj>([]); Expected #1, Actual #0.
What do I need to do to set up a parameter to pass into the AllSearchBy in my repository?
Thanks in advance for any help!!

What if you try to pass following as an argument instead of current myFunc:
Arg<Expression<Func<MyObj, bool>>[]>.Is.Anything

Related

Laravel Controller/Modal order by in all()

Trying to sort my table. The numbers are category_id and they are not sorted by number (1 and 2 are at the bottom of the table), I want to order them.
Controller:
public function fetchcategory(){
$all_categories = HmsBbrCategory::all();
return response()->json([
'all_categories'=>$all_categories,
]);
}
When I try the code below, I get 500 internal server error in my console:
$all_categories = HmsBbrCategory::orderBy('category_id', 'ASC')->all();
What am I doing wrong witht the orderBy code?
Just for reference to know difference between all() and get()
all()
Its a static method so you cant execute additional queries.Only option you have in all() method is you can select columns.
public static function all($columns = ['*'])
{
return static::query()->get(
is_array($columns) ? $columns : func_get_args()
);
}
If we see implementation of that static all() method. Internally it calls get() method
1.all() accept columns as array. Default set to * ,it means all columns selected.
2.Inside of that method ,we can see get() called. So after get we cant call any query operations so its throwing error
get() is Eloquent builder \Illuminate\Database\Eloquent\Builder
Simply you have to update this line
$all_categories = HmsBbrCategory::orderBy('category_id', 'ASC')->all();
into
$all_categories = HmsBbrCategory::orderBy('category_id', 'ASC')->get();
then you will get your result .

Mocking MailController with ActionMailer.net using Moq 3

I'm new to Moq, so any help would be great. I keep getting a null reference error in my code when I'm trying to set up a test. Here is the line of code where I'm getting the error below.
_iMailController.RequesterEmail(model).Deliver();
Here is what my test looks like:
_mockMailController = new Mock<IMailController>();
mockMailController .Setup(x => x.RequesterEmail(new Model())).Returns(**new EmailResult()**);
The bold part is where I'm stuck at. It takes 7 parameters and dont know what to put to fake out the EmailResult.
You are confusing, The Return part will single return values like string, list, bool or Int ect.
So you can easily pass the value which you get in return on the RequesterEmail on the IMailController. So you have to check the which value get retun from the RequesterEmail method.
You may also use the below code as example:
mockMailController .Setup(x => x.RequesterEmail(It.IsAny<Model>())).Returns(**new EmailResult()**);
Refet the below Part too.
It mentioned about how many parameter you passed in the RequesterEmail method. If there is 7 parameters passed on the method then you may have to pass 7 parmeter like bleow
Please look deeply in parameter and return on both codes down here.
And look where i use ModelClass in both below codes.
If the Method have parameters like below:
public void RequesterEmail( string, int, list, EmailClass, someClass, bool, string);
{
return ModelClass;
}
then you may have to write the code as below
mockMailController .Setup(x => x.RequesterEmail(It.IsAny<string>(), It.IsAny<int>(),
It.IsAny<EmailClass>(), It.IsAny<someClass>(), It.IsAny<bool>(),
It.IsAny<string>())).Return(ModelClass)

How to build LINQ queries for NHibernate which contain function calls?

A few weeks ago I decided to switch from using Linq to SQL to use NHibernate instead. (Reasons include: other Java-based projects use Hibernate; target DB not yet decided; multiple DBs may have to be targeted)
Anyway, I wanted to continue using LINQ and saw that NHibernate has LINQ support. I want to have a small nummber of object access methods and be able to pass a LINQ expression which filters the query but it has not worked as expected.
Here is an example based on the PredicateBuilder from http://www.albahari.com/nutshell/predicatebuilder.aspx
public static Expression<Func<Product, bool>> ContainsInDescription(params string[] keys)
{
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keys)
{
string temp = keyword.ToLower();
predicate = predicate.Or(p => p.Description.Contains(temp));
}
return predicate;
}
The Predicate.False statment causes the following error message:
Atf.NUnit.Model.TestLinq.TestProductCID():
System.Exception : Could not determine member type from Constant, False, System.Linq.Expressions.ConstantExpression
The p.Description.Contains statement causes this error message:
Atf.NUnit.Model.TestLinq.TestProductCID():
System.Exception : Could not determine member type from Invoke, Invoke(p => p.Description.Contains(value(Atf.Model.Linq.ProductLinq+<>c__DisplayClass2).temp), f), System.Linq.Expressions.InvocationExpression
I get similar errors when using string.Equals and other such methods.
Am I doing something wrong here? Should I use a different approach?

WebAPI and OData - returning Queryable with preconditions

I have a simple GET method, which returns IQueryable, and has some preconditions on query:
[Queryable(HandleNullPropagation = HandleNullPropagationOption.False)]
public IQueryable<Message> Get()
{
using (var session = RavenStore.GetSession())
{
var messages = session.Query<Message>().Where(x => x.TargetUserId == this.User.Identity.Name || x.SourceUserId == this.User.Identity.Name);
return messages;
}
}
This is RavenDB, btw. The issue I'm having is that upon execution the user id is replaced with "[EMPTY_STRING]", so the actual query its running is this:
'TargetUserId:[[EMPTY_STRING]] OR SourceUserId:[[EMPTY_STRING]]' on
index .....
which is obviously wrong.
If I'm returning List instead of IQueriable - it works fine, so something later in the pipeline changes the query. Does anyone have any insight on how to make this work ?
It should work when the values are copied to a local variable first:
var userName = this.User.Identity.Name;
return session.Query<Message>()
.Where(x => x.TargetUserId == userName ||
x.SourceUserId == userName);
This is because by the time the query is executed, the Raven Client query translator can't resolve the objects expressed in the predicate. By copying them into a local variable, you are passing a constant value into the expression.
I believe this is related to closures. Perhaps someone with more direct knowledge of expression trees can explain better in comments.

Why does this Machine.Fakes parameter matching throw an exception?

I'm using Machine.Fakes.NSubstitute and want to "fake" a return value such that if the input parameter matches a specific value it returns the mock object, otherwise it returns null.
I tried the following:
host.WhenToldTo(h => h.GetTenantInstance(Param.Is(new Uri("http://foo.bar"))))
.Return(new TenantInstance());
But it throws the following exception:
System.InvalidCastException: Unable to cast object of type
'System.Linq.Expressions.NewExpression' to type
'System.Linq.Expressions.ConstantExpression'.
My current workaround is to do the following:
host.WhenToldTo(h => h.GetTenantInstance(Param.IsAny<Uri>()))
.Return<Uri>(uri => uri.Host == "foo.bar" ? new TenantInstance() : null);
Which is a bit smelly.
I see three aspects here:
When a method with a reference type return value is called on a mock object and no behavior has been set up for the call, the mock object will return a mock. If you want it to return null instead, you have to configure that explicitly. Thus, it is not enough to set up
host.WhenToldTo(h => h.GetTenantInstance(Param.Is(new Uri("http://foo.bar"))))
.Return(new TenantInstance());
You also have to set up the other case with something like this:
host.WhenToldTo(h => h.GetTenantInstance(Param<Uri>.Matches(x => !x.Equals(new Uri("http://foo.bar")))))
.Return((TenantInstance)null);
I find your "workaround" solution more elegant than these two setups.
When you match a method call argument for equality, there is no need to use Param.Is(). You can simply set up the behavior with
host.WhenToldTo(h => h.GetTenantInstance(new Uri("http://foo.bar")))
.Return(new TenantInstance());
The fact that you get an exception when using Param.Is() here is a shortcoming of Machine.Fakes. I see not reason why this should not work. I will correct that at some point and let you know.