Facing issue when trying to fake helper function - asp.net-mvc-4

I am using Nunit and FakeItEasy for my MVC Controller functions.
My Test Code:
[Test]
public async Task Search_Success()
{
if (!isFakeInitialized)
InitializeFake();
url = "/N/UserSvc/v1/Types?skip=0&take=" + Constants.MaxSearchRowNumber;
Types= A.CollectionOfFake<Type>(3);
List<Type> found=new List<Type>(Types);
A.CallTo(() => nFake.GetDataAsync<IEnumerable<Type>>(fakeHttpSession, url)).Returns(Types);
var fakeHelper = A.Fake<helperFunctions>();
A.CallTo(() => FakeHelper.GetAvailableTypes(fakeHttpSession, found, true)).Returns(foundTypes);
//Act
var actionResult = await myController.SearchView();
var viewResult = actionResult as ViewResult;
//Assert
Assert.IsNotNull(viewResult);
Assert.AreEqual("Search", viewResult.ViewName);
}
I am getting error at
A.CallTo(() => nFakeHelper.GetAvailableTypes(fakeHttpSession, found, true)).Returns(foundTypes);
Error: cannot convert lambda expression to type object because it is not a delegate type.
Here is the helper function Code:
public List GetAvailableTypes(Session session,List allTypes,bool includeAllType)
{
List results = new List();
return results;
}
How can i overcome the error.

If nothing else, your A.CallTo should fail because GetAvailableLicenseTypes isn't virtual. I'm a little surprised at the error message, though.
I've tried to reproduce, but had to trim things down quite a bit and fill in missing code, and ended up getting
The current proxy generator can not intercept the specified method for the following reason:
- Non virtual methods can not be intercepted.
Are you able to include more information, starting with the full error, including stack trace?

var nmsFakeHelper = A.Fake<NMCHelperFunctions>();
A.CallTo(() => nmsFakeHelper.GetAvailableLicenseTypes(fakeHttpSession, foundLicense, true)).Returns(foundLicensTypes);
These two lines are your issue.
The first line declares nmsFakeHelper as a fake of concrete type NMCHelperFunctions.
The second line then defines the behaviour of the fake when it's GetAvailableLicenseTypes method is called.
In the background, FakeItEasy decides what type of fake it should use (mock, stub, etc.). If the type you are asking a fake of is concrete you get a stub. However, if you want to be able to define behaviour (define return values or validate that methods were called etc.) you need a mock instead of a stub.
To get FakeItEasy to decide to return a mock instead of a stub, you need to give it an interface type instead. This is because a mock needs to be able to intercept the method calls but in .NET, methods can only be intercepted if they are virtual calls. This happens when the type you are using is an interface, but cannot happen when the type you are using is a concrete type.
So to get around this problem, you should add an interface to the NMCHelperFunctions type that includes (at the very least) the GetAvailableLicenseTypes method (as well as any other methods you may).
This means that your first line will change to the following (assuming you name your interface iNMCHelperFunctions):
var nmsFakeHelper = A.Fake<iNMCHelperFunctions>();
Your second line would remain unchanged, and your test code should now work.
You may have to refactor your application code to use the interface type instead of the concrete type. There is some benefit from doing this because it allows your components to be swappable so it's easier to add or change behaviour in the future by writing a new class that adheres to the same interface and switching to that.

Related

How to test a service method that returns a model?

So I have a service method that modifies a model object
public function doSomething() {
$model = new Model();
// Modify the model with a bunch of private methods
return $model;
}
If I want to test doSomething, I really only have $model to work with. And the only way I can write assertions on $model is to use its public interfaces.
$this->assertEquals($model->getName(), 'name');
What confuses me here is what exactly am I testing with that assertion? Am I testing that getName works properly or am I testing doSomething works properly?
In order for me to test doSomething, I have to assume that getName works. So how do I make sure that is the case?
Based on your code, I would test that I got an instance of Model returned. And then using the public accessors or assertAttributeEquals to check that the properties of the object were correct. This does test the getters of the model, however the object having certain properties is what you are expecting to happen.
Though as your class is both creating the object and modifying it. I would change the method to take a Model as an argument. This way in my test I can create a mockModel and make sure that any public setters are called with the proper arguments. Doing this, I don't have to worry about any of the logic that Model has for properties that get set.
For Example:
Test Function:
public function testDoSomething() {
$mockModel = $this->getMock('Model');
$mockModel->expects($this->once())
->method('foo')
->with('some argument');
$mockModel->expects($this->once())
->method('bar')
->with('some other argument');
$sut = new SUT();
$sut->doSomething($mockModel);
}
Your function doSomething only needs to become this:
public function doSomething(Model $model) {
/** Do stuff with private methods **/
}
Now you are able to make sure that properties of Model are set with the proper values and not depending on the logic that may or may not exist in the class. You are also helping to specify the contract that Model needs to fill. Any new methods that you are depending on will come out in your integration / system tests.
Your contract with doSomething() is, that it has to return an object of type "Model". Your contract is not getName() working on a returned object. As result, test $model to be of correct type:
$this->assertInstanceOf('Model', $model);
Documentation: PHPUnit -> assertInstanceOf()
As a hint, "[i]deally, each test case is independent from the others" 2014-10-21 wikipedia.org/wiki/Unit_testing.
So, in your test_doSomethingTest*(), you are supposed to test only what happens within that function. Check for return type, and whatever happens withing that function. Testing getName() should be in it's own test_getName*().

Ninject Factory - "new" object being passed in instead of one called in factory method

I am using the Ninject Factory Extensions so that I can create objects that have services injected plus custom values
so:
public interface IGameOperationsFactory
{
ISpinEvaluator Create(GameArtifact game);
IReelSpinner CreateSpinner(GameArtifact game);
}
Then in module:
Bind<IGameOperationsFactory>().ToFactory().InSingletonScope();
Bind<ISpinEvaluator>().To<DefaultSpinEvaluatorImpl>();
Bind<IReelSpinner>().To<DefaultReelSpinnerImpl>();
The actual factory gets injected in a classes' constructor and is then used like:
_spinner = _factory.CreateSpinner(_artifact);
_spinEval = _factory.Create(_artifact);
Where _artifact is of type GameArtifact
Then in each of the implementation's constructors services plus the passed in objects are injected. The GameArtifact is successfully passed in the first constructor, and in the second one a "new" GameArtifact is passed in, i.e. not a null one but one with just default values as if the framework just called
new GameArtifact()
instead of passing in the already existing one!
The Constructor for the two objects is very similar, but the one that doesn't work looks like:
[Inject]
public DefaultReelSpinnerImpl(GameArtifact ga, IGameOperationsFactory factory, IRandomService serv)
{
_rand = serv;
_ra = ga.Reels;
_mainReels = factory.Create(_ra);
_winLine = ga.Config.WinLine;
}
Where the factory and serv are injected by Ninject and ga is SUPPOSED to be passed in via the factory.
Anyone have a clue why a new "fresh" object is passed in rather than the one I passed in??
I have rewritten you sample a little bit, and it seems to work fine. Could you provide more detailed code sample?
My implementation
I have changed verb Create to Get to match Ninject conventions
public interface IGameOperationsFactory
{
ISpinEvaluator GetSpinEvaluator(GameArtifact gameArtifact);
IReelSpinner GetReelSpinner(GameArtifact gameArtifact);
}
Ninject configuration
I have added named bindings to configure factory
Bind<ISpinEvaluator>()
.To<DefaultSpinEvaluatorImpl>()
.Named("SpinEvaluator");
Bind<IReelSpinner>()
.To<DefaultReelSpinnerImpl>()
.Named("ReelSpinner");
Bind<IGameOperationsFactory>()
.ToFactory();
ps: full sample with tests

AutoFac WCF proxy with changing ClientCredentials

I'm writing a WCF service and am using the AutoFac WCF integration for DI. I have a slightly weird situation where I have a proxy to another service that requires credentials. The credentials will change based on some parameters coming in so I can't just set the values when I'm setting up the container and be done with it.
public class MyService : IMyService
{
private ISomeOtherService _client;
public MyService(ISomeOtherService client)
{
_client = client;
}
public Response SomeCall(SomeData data)
{
// how do I set ClientCredentials here, without necessarily casting to concrete implementation
_client.MakeACall();
}
}
What's the best way to set the credentials on proxy without having to cast to a known type or ChannelBase. I'm trying to avoid this because in my unit tests I'm mocking out that proxy interface so casting it back to one of those types would fail.
Any thoughts?
You can do it, but it's not straightforward, and you have to slightly change the design so the logic of "decide and set the credentials" is pulled out of the MyService class.
First, let's define the rest of the classes in the scenario so you can see it all come together.
We have the ISomeOtherService interface, which I've modified slightly just so you can actually see what credentials are getting set at the end. I have it return a string instead of being a void. I've also got an implementation of SomeOtherService that has a credential get/set (which is your ClientCredentials in WCF). That all looks like this:
public interface ISomeOtherService
{
string MakeACall();
}
public class SomeOtherService : ISomeOtherService
{
// The "Credentials" here is a stand-in for WCF "ClientCredentials."
public string Credentials { get; set; }
// This just returns the credentials used so we can validate things
// are wired up. You don't actually have to do that in "real life."
public string MakeACall()
{
return this.Credentials;
}
}
Notice the Credentials property is not exposed by the interface so you can see how this will work without casting the interface to the concrete type.
Next we have the IMyService interface and associated request/response objects for the SomeCall operation you show in your question. (In the question you have SomeData but it's the same idea, I just went with a slightly different naming convention to help me keep straight what was input vs. what was output.)
public class SomeCallRequest
{
// The Number value is what we'll use to determine
// the set of client credentials.
public int Number { get; set; }
}
public class SomeCallResponse
{
// The response will include the credentials used, passed up
// from the call to ISomeOtherService.
public string CredentialsUsed { get; set; }
}
public interface IMyService
{
SomeCallResponse SomeCall(SomeCallRequest request);
}
The interesting part there is that the data we're using to choose the set of credentials is the Number in the request. It could be whatever you want it to be, but using a number here makes the code a little simpler.
Here's where it starts getting more complex. First you really need to be familiar with two Autofac things:
Implicit relationships - we can take a reference on a Func<T> instead of a T to get a "factory that creates T instances."
Using parameters from registration delegates - we can take some inputs and use that to inform the outputs of the resolve operation.
We'll make use of both of those concepts here.
The implementation of MyService gets switched to take a factory that will take in an int and return an instance of ISomeOtherService. When you want to get a reference to the other service, you execute the function and pass in the number that will determine the client credentials.
public class MyService : IMyService
{
private Func<int, ISomeOtherService> _clientFactory;
public MyService(Func<int, ISomeOtherService> clientFactory)
{
this._clientFactory = clientFactory;
}
public SomeCallResponse SomeCall(SomeCallRequest request)
{
var client = this._clientFactory(request.Number);
var response = client.MakeACall();
return new SomeCallResponse { CredentialsUsed = response };
}
}
The real key there is that Func<int, ISomeOtherService> dependency. We'll register ISomeOtherService and Autofac will automatically create a factory that takes in an int and returns an ISomeOtherService for us. No real special work required... though the registration is a little complex.
The last piece is to register a lambda for your ISomeOtherService instead of a simpler type/interface mapping. The lambda will look for a typed int parameter and we'll use that to determine/set the client credentials.
var builder = new ContainerBuilder();
builder.Register((c, p) =>
{
// In WCF, this is more likely going to be a call
// to ChannelFactory<T>.CreateChannel(), but for ease
// here we'll just new this up:
var service = new SomeOtherService();
// The magic: Get the incoming int parameter - this
// is what the Func<int, ISomeOtherService> will pass
// in when called.
var data = p.TypedAs<int>();
// Our simple "credentials" will just tell us whether
// we passed in an even or odd number. Yours could be
// way more complex, looking something up from config,
// resolving some sort of "credential factory" from the
// current context (the "c" parameter in this lambda),
// or anything else you want.
if(data % 2 == 0)
{
service.Credentials = "Even";
}
else
{
service.Credentials = "Odd";
}
return service;
})
.As<ISomeOtherService>();
// And the registration of the consuming service here.
builder.RegisterType<MyService>().As<IMyService>();
var container = builder.Build();
OK, now that you have the registration taking in an integer and returning the service instance, you can just use it:
using(var scope = container.BeginLifetimeScope())
{
var myService = scope.Resolve<IMyService>();
var request = new SomeCallRequest { Number = 2 };
var response = myService.SomeCall(request);
// This will write "Credentials = Even" at the console
// because we passed in an even number and the registration
// lambda executed to properly set the credentials.
Console.WriteLine("Credentials = {0}", response.CredentialsUsed);
}
Boom! The credentials got set without having to cast to the base class.
Design changes:
The credential "set" operation got moved out of the consuming code. If you don't want to cast to the base class in your consuming code, you won't have a choice but to also pull the credential "set" operation out. That logic could be right in the lambda; or you could put it in a separate class that gets used inside that lambda; or you could handle the OnActivated event and do a little magic there (I didn't show that - exercise left to the reader). But the "tie it all together" bit has to be somewhere in the component registration (the lambda, the event handler, etc.) because that's the only point at which you still have the concrete type.
The credentials are set for the lifetime of the proxy. It's probably not good if you have a single proxy in your consuming code where you set different credentials just before you execute each operation. I can't tell from your question if that's how you have it, but... if that's the case, you will need a different proxy for each call. That may mean you actually want to dispose of the proxy after you're done with it, so you'll need to look at using Owned<T> (which will make the factory Func<int, Owned<T>>) or you could run into a memory leak if services are long-lived like singletons.
There are probably other ways to do this, too. You could create your own custom factory; you could handle the OnActivated event that I mentioned; you could use the Autofac.Extras.DynamicProxy2 library to create a dynamic proxy that intercepts calls to your WCF service and sets the credentials before allowing the call to proceed... I could probably brainstorm other ways, but you get the idea. What I posted here is how I'd do it, and hopefully it will at least point you in a direction to help you get where you need to go.
The approach we ended up taking is to cast ISomeOtherService to ClientBase,
This avoids referencing the proxy type. Then in our unit tests we can set up the mock like so
var client = new Mock<ClientBase<ISomeOtherService>>().As<ISomeOtherService>();
So it can be casted to ClientBase, but still setup as ISomeOtherService

Can a RhinoMock mock hold property values?

I have been stuck on this for a day or two, I have recently started using RhinoMocks (v3.5)and I have setup a test. A stub web service that returns a List collection and a class that calls it, and a mock object with a property i expect to be set as a result of the call to the web service. My code is like this:
[Test]
public void Call_WebService_list_populated()
{
IData stService = MockRepository.GenerateStub<IData>();
IDefault mockView = MockRepository.GenerateMock<IDefault>();
DefaultPresenter presenter = new DefaultPresenter(mockView);
presenter.StService = stService;
mockView.Stub(x => x.RequestingUser).Return("test");
List<string> testList = new List<string> { new string() };
stService.Stub(x => x.GetList("test")).Return(testList);
presenter.LoadList();
Assert.AreEqual(testList,mockView.List);
}
In the LoadList function it just assigns the List property of mockView the list returned from the webservice. I can get the test to work using this line:
mockView.AssertWasCalled(a => a.StoryListing = testList);
but i expected that the mock object would hold state and i could check the property directly. Am i doing something wrong or is this just the way you have to use rhino mocks ie: the mock object cant hold state as when i do the assert.areequal nunit says the mockView.List property is null.
By default, mocks don't handle get/set properties (not sure why. There's a way to change it but I can't remember offhand). You can generate your mockView as a stub (MockRepository.GenerateStub<IDefault>()) -- and stubs support property behavior.

Property chaining in RhinoMocks

I have a class TxRx with a property called Common. Common then has a property called LastMod. I want to write a RhinoMock expectation to show that LastMod has been set with something. So I tried:
var txRx = MockRepository.GenerateMock<TxRx>();
var common = MockRepository.GenerateMock<Common>();
txRx.Expect(t => t.Common).Return(common);
txRx.Expect(t => t.Common.LastMod).SetPropertyAndIgnoreArgument();
But I get the following exception:
System.InvalidOperationException: Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
at Rhino.Mocks.LastCall.GetOptions[T]()
at Rhino.Mocks.RhinoMocksExtensions.Expect[T,R](T mock, Function`2 action)
at ...
I presume this means Common needs to be virtual, but as it is a property on a LinqToSql generated class I can't make it virtual (other than hacking the autogen code which is not really an option).
Is there any way around this?
One possibility is to wrap TxRx in a mockable class (i.e. one that has overridable methods and properties which you wish to mock out or implements an interface which defines the properties or methods that you're interested in) and then pass around the wrapper rather than the LinqToSQL class itself.
Perhaps something like the following:
public class TxRxWrapper : ITxRxWrapper
{
private TxRx m_txrx;
public object LastMod
{
get { return m_txrx.Common.LastMod; }
}
...
}
public interface ITxRxWrapper
{
public object LastMod { get; }
...
}
Not ideal (i.e. it can get somewhat cumbersome to pass wrappers around just for mockability!) but that's the only way you can get RhinoMocks to mock properties/methods for you.
The other option is to use TypeMock instead which I believe uses a different mechanism to mock stuff out. I don't think it's free, though.
You would need to replace your second expectation with
txRx.Expect(() => common.LastMod).SetPropertyAndIgnoreArgument();
But the Common property itself needs to be virtual for this to work.