How can I moq this query against ravendb - nunit

I have this code in my project, how can I use Moq to moq the documentsession and setup the return value?
_session.Query<IPageModel, PageByUrl>()
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.FirstOrDefault(x => x.Metadata.Url == virtualUrl);
This is what I have tried before I asked
var session = new Mock<IDocumentSession>();
var pageModel = new DummyModel();
session.Setup(x => x.Query<IPageModel, PageByUrl>()
.Customize(y => y.WaitForNonStaleResultsAsOfLastWrite())
.FirstOrDefault(y => y.Metadata.Url == path)).Returns(pageModel);
This throws an exception and I can't figure out how to change the moq
System.NotSupportedException : Expression references a method that does not belong to the mocked object: x => x.Query<IPageModel,PageByUrl>().Customize(y => y.WaitForNonStaleResultsAsOfLastWrite()).FirstOrDefault<IPageModel>(y => y.Metadata.Url == .path)
at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b()
at Moq.Mock.Setup(Mock mock, Expression`1 expression, Func`1 condition)
at Moq.Mock`1.Setup(Expression`1 expression)
at BrickPile.Tests.Web.Routing.PathResolverTests.Home_Page_With_Default_Action(String path) in PathResolverTests.cs: line 26

Instead of mocking the document session, have you thought about using the embeddabledocumentstore? It could run completely in memory and you have the full database as backend for your tests.
See also this blog post which describes some of the backgrounds: http://novuscraft.com/blog/ravendb-and-the-repository-pattern

This question inspired a blog post.
The short answer: Don't. You're coupling your application to RavenDB and violating the Interface Segregation Principle. Instead, write a custom interface that specifies precisely what services your class (the system under test) needs. Write a wrapper class that implements that and delegates to RavenDB. This might use the Repository Pattern, or it might be something simpler. Your interface should be simple to mock.

You need to mock whatever IDocumentSession.Query() returns as a separate mock so that you can then setup the customize call. I'm typing this on my phone so I can't easily give you an example.

Related

How can I fake a Class used insite SUT using FakeItEasy

Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.

How to call constructor with interface arguments when mocking a concrete class with Moq

I have the following class, which uses constructor injection:
public class Service : IService
{
public Service(IRepository repository, IProvider provider) { ... }
}
For most methods in this class, I simply create Moq mocks for IRepository and IProvider and construct the Service. However, there is one method in the class that calls several other methods in the same class. For testing this method, instead of testing all those methods together, I want to test that the method calls those methods correctly and processes their return values correctly.
The best way to do this is to mock Service. I've mocked concrete classes with Moq before without issue. I've even mocked concrete classes that require constructor arguments with Moq without issue. However, this is the first time I've needed to pass mocked arguments into the constructor for a mocked object. Naturally, I tried to do it this way:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
However, that does not work. Instead, I get the following error:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service.
Could not find a constructor that would match given arguments:
Castle.Proxies.IRepository
Castle.Proxies.IProvider
This works fine if Service's constructor takes simple arguments like ints and strings, but not if it takes interfaces that I'm mocking. How do you do this?
Why are you mocking the service you are testing? If you are wishing to test the implementation of the Service class (whether that be calls to mocked objects or not), all you need are mocks for the two interfaces, not the test class.
Instead of:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
Shouldn't it be this instead?
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Service(repository.Object, provider.Object);
I realize that it is possible to mock concrete objects in some frameworks, but what is your intended purpose? The idea behind mocking something is to remove the actual implementation so that it does not influence your test. But in your question, you have stated that you wish to know that certain classes are called on properly, and then you wish to validate the results of those actions. That is undoubtedly testing the implementation, and for that reason, I am having a hard time seeing the goals of mocking the concrete object.
I had a very similar problem when my equivalent of Service had an internal constructor, so it was not visible to Moq.
I added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
to my AssemblyInfo.cs file for the implementing project. Not sure if it is relevant, but I wanted to add a suggestion on the off chance that it helps you or someone else.
It must be old version issue, all is ok with latest version. Nick, Please check!
P.s.: I started bounty by misstake (I had wrong signature in my constructor).

How to update a property on a parameter using FakeItEasy

I have an interface that includes a member that looks like:
void ExecuteSqlCommand(string procedureName, SqlParameter[] parameters);
I am using FakeItEasy to create a mock of this to pass to one of my classes.
The code I am testing calls this method, then checks the value of one of the SqlParameters. How do I use FakeItEasy to set the Value property of this parameter when the method is called?
I appreciate that this is probably not the best practice for getting individual pieces of information out of a database, but I am working with existing stored procedures, some of which have OUT parameters.
As you say, this is probably not the best practice. That aside, I guess you could do something like this:
A.CallTo(() => fake.ExecuteSqlCommand(A<string>._, A<SqlParameter[]>._))
.Invokes((string s, SqlParameter[] p) => p[someIndex].Value = yourValue);
Or, using a less-readable but more powerful overload, access a IFakeObjectCall directly:
A.CallTo(() => fake.ExecuteSqlCommand(A<string>._, A<SqlParameter[]>._))
.Invokes(callObject => callObject.GetArgument<SqlParameter[]>("parameters")[someIndex].Value = yourValue);

Autofac registration with multiple assembies and differing EntityConnections

We have two Assemblies that contain their own Entity-Framework EDMX & repositoriy objects. These are registered using Autofac in an ASP.NET webapplication.
These Assemblies are very similar of architecture (but differing EDMX) we have found that the last EntityConnection being registered is the EntityConnection that is being used in both Assemblies. We need to limit the usage of an EntityConnection to only be used by Types of an assembly or namespace.
var assembly = typeof(Activity).Assembly;
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
builder.Register(reg => new EntityConnection(ConnectionString));
var assembly = typeof(User).Assembly;
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
builder.Register(reg => new EntityConnection(ConnectionString));
Is there a way to register the EntityConnection and limit the depth of EntityConnection? Limit each EntityConnection to the assembly it belong to?
Here's a pseudocode example of how we want to register EntityConnection for use in only an assembly or namespace.
builder.Register(reg => new EntityConnection(ConnectionString)).ForNamespace("x");
try to solve the problem at an higher level of abstraction. Since you have two separate domains (one containing the Activity entity, and one containing the User entity), it would be convenient to have this explicitly in your application design. For instance, define a factory of some kind per domain:
public interface IActivityDomainContextFactory
{
ObjectContext CreateNew();
}
public interface IPeopleDomainContextFactory
{
ObjectContext CreateNew();
}
You can now easily create an implementation for each interface, register them in the Autofac ContainerBuilder and let your services depend on one of those interfaces, instead of depending them on a EntityConnection.
In this case you of course still have a dependency on the Entity Framework itself (see here for how to abstract that away), but this makes your configuration much easier, less fragile, better performing, and your application code more maintainable.
I hope this helps.
You probably want to name/key your registrations. See TypedNamedAndKeyedServices - Autofac
I think this solves half your problem, how to register the types. The other half is in the resolution. Since your doing autoregistration via assembly scanning, this might take a little more trickery.
There are plenty of good suggestions out there on improving this, so just recording my solution as a general sketch of how you'd do this in Autofac.
The trick is to use named services for the connections, then customise parameter resolution for types in each assembly so that the EntityConnection parameters get a named instance:
builder.Register(reg => new EntityConnection(ConnectionString))
.Named<EntityConnection>("activities");
builder.RegisterAssemblyTypes(typeof(Activity).Assembly)
.AsImplementedInterfaces()
.WithParameter(
(pi, c) => pi.ParameterType == typeof(EntityConnection),
(pi, c) => c.ResolveNamed<EntityConnection>("activities"));
builder.Register(reg => new EntityConnection(ConnectionString))
.Named<EntityConnection>("users");
builder.RegisterAssemblyTypes(typeof(User).Assembly)
.AsImplementedInterfaces()
.WithParameter(
(pi, c) => pi.ParameterType == typeof(EntityConnection),
(pi, c) => c.ResolveNamed<EntityConnection>("users"));

How to carry out custom initialisation with autofac

I'm adding autofac to an existing project and some of the service implementations require their Initialize method to be called and passed configuration information. Currently I'm using the code:
builder.Register(context =>
{
var service =
new SqlTaxRateProvider(context.Resolve<IUserProvider>());
service.Initialize(config);
return service;
}
).As<ITaxService>()
.SingleInstance();
which works but I'm still creating the object myself which is what I'm trying to get away from this and allow autofac to handle it for me. Is it possible to configure a post create operation that would carry out the custom initialisation?
To give you an idea of what I'm after ideally this would be the code:
builder.RegisterType<SqlTaxRateProvider>()
.As<ITaxService>()
.OnCreated(service=> service.Initialize(config))
.SingleInstance();
Update:
I am using Autofac-2.1.10.754-NET35
.OnActivating(e => e.Instance.Initialize(...))
should do the trick.
You might also investigate the Startable module (see the Startable entry in the Autofac wiki).
Mark's suggestion to do initialisation in the constructor is also a good one. In that case use
.WithParameter(new NamedParameter("config", config))
to merge the config parameter in with the other constructor dependencies.