Using typemock for chaining - c#

I am just starting here with mocking about, and I am trying something which I think should be quite simple.
I have a class that reads Google calendar data. First, it creates a CalendarService object, then it calls Query on that object, receives a EventFeed and iterates on the Item collection of AtomEntryCollection.
I want it all to be mocked, as I don't want my tests to send any web requests around.
I tried mocking it all with
var service = MockManager.Mock<CalendarService>();
var events = MockManager.MockAll<EventFeed>();
var entries = MockManager.MockAll<AtomEntryCollection>();
service.ExpectAndReturn("Query", events.MockedInstance);
events.ExpectGet("Entries", entries.MockedInstance);
entries.ExpectGetAlways("Count", 3);
but my test fails as soon as the object returned from the service.Query() method is used. I understand that in the 5th line the entries.MockedInstance was still null, so the ExpectAndReturn recorded the null as the return value - so what am I supposed to do? How can I set the mocks to return valid mock objects, instead of nulls?
Note - I am writing a .NET 2.0 project, so I can't use the Isolator features (I think). Would that have helped me? Or maybe switching to Rhino or MOQ would make it all easier?

First, if you're using the old API, you should use MockObject, not Mock. Mock is for objects that are created later in the code under test, MockObject is for object that get created now.
But why use the old API? The best way I recommend, is write the tests in .Net 3.5, this way you get best of both worlds. In this case your setup looks like this:
var service = Isolate.Fake.Instance();
Isolate.WhenCalled(() => service.Query().Count).WillReturn(3);
var events = Isolate.Fake.Instance();
Isolate.WhenCalled(() => events.Entries.Count).WillReturn(3);
If however, you're hard pressed to use 2.0 no Lambda syntax, this is how it looks like:
var service = Isolate.Fake.Instance();
Isolate.WhenCalled(delegate { return service.Query().Count; }).WillReturn(3);
events = Isolate.Fake.Instance();
Isolate.WhenCalled(delegate { return events.Entries.Count; }).WillReturn(3);
Refer to this link on how to setup a VS2005 test to work with AAA API.

Related

How Can I Redesign My C# Application To Avoid Constructor Injection Overload?

I am still new to DI and Unit Tests. I have been tasked with adding Unit Tests to some of our legacy code. I am working on a WCF web service. A lot of refactoring has had to be done. Monster classes split into separate classes that make sense. Monster methods split to multiple methods. And lastly, creating interface classes for external dependencies. This was done initially to facilitate mocking those dependencies for unit tests.
As I have gone about this the list of dependencies keeps growing and growing. I have other web services to call, SQL Servers and DB2 Databases to interact with, a config file to read, a log to write to, and reading from Sharepoint data. So far I have 10 dependencies. And every time I add one it breaks all my Unit Tests since there is a new parameter in the constructor.
If it helps, I am using .Net 4.5, Castle Windsor as my IOC, MSTest, and Moq for testing.
I have looked here How to avoid Dependency Injection constructor madness? but this doesn't provide any real solution. Only to say "your class may be doing too much." I looked into Facade and Aggregate services but that seemed to just move where things were.
So I need some help on how to make this class to "less" but still provide the same output.
public AccountServices(ISomeWebServiceProvider someWebServiceProvider,
ISomeOtherWebProvider someOtherWebProvider,
IConfigurationSettings configurationSettings,
IDB2Connect dB2Connect,
IDB2SomeOtherData dB2SomeOtherData,
IDB2DatabaseData dB2DatabaseData,
ISharepointServiceProvider sharepointServiceProvider,
ILoggingProvider loggingProvider,
IAnotherProvider AnotherProvider,
ISQLConnect SQLConnect)
{
_configurationSettings = configurationSettings;
_someWebServiceProvider = someWebServiceProvider;
_someOtherWebProvider = someOtherWebProvider;
_dB2Connect = dB2Connect;
_dB2SomeOtherData = dB2SomeOtherData;
_dB2DatabaseData = dB2DatabaseData;
_sharepointServiceProvider = sharepointServiceProvider;
_loggingProvider = loggingProvider;
_AnotherProvider = AnotherProvider;
_SQLConnect = SQLConnect;
}
Almost all of the there are in other components but I need to be able to use them in the main application and mock them in unit tests.
Here is how one of the methods is laid out.
public ExpectedResponse GetAccountData(string AccountNumber)
{
// Get Needed Config Settings
...
// Do some data validation before processing data
...
// Try to retrieve data for DB2
...
// Try to retrieve data for Sharepoint
...
// Map data to response.
...
// If error, handle it and write error to log
}
Other methods are very similar but they may be reaching out to SQL Server or one or more web services.
Ideally what I would like to have is an example of an application that needs a lot of dependencies, that has unit tests, and avoids having to keep adding a new dependency to the constructor causing you to update all your unit tests just to add the new parameter.
Thanks
Not sure if this helps, but I came up with a pattern I called GetTester that wraps the constructor and makes handling the parameters a little easier. Here's an example:
private SmartCache GetTester(out Mock<IMemoryCache> memory, out Mock<IRedisCache> redis)
{
memory = new Mock<IMemoryCache>();
redis = new Mock<IRedisCache>();
return new SmartCache(memory.Object, redis.Object);
}
Callers look like this if they need all the mocks:
SmartCache cache = GetTester(out Mock<IMemoryCache> memory, out Mock<IRedisCache> redis);
Or like this if they don't:
SmartCache cache = GetTester(out _, out _);
These still break if you have constructor changes, but you can create overloads to minimize the changes to tests. It's a hassle but easier than it would otherwise be.
So possibly your classes might be doing too much. If you're finding that you're constantly increasing the work that a class is doing and as a result are needing to provide additional objects to assist in those additional tasks then this is probably the issue and you need to consider breaking up the work.
However, if this isn't the case then another option is to have the classes take in a reference to a dependency class that provides access to either the instantiated concrete objects that implement your various interfaces or instantiated factory objects which can be used to construct objects. Then instead of constantly passing new parameters you can just pass the single object and from there pull or create objects as necessary from that.

How to Mock a Service with Moq and Nunit in mvc application - prevent nulls

I was under the impression that mocking is faking data calls thus nothing is real. So when I trying to create my own Unit Test that are very similar to what other developers on my team are doing, I am thinking that this is not correct to be newing up the service.
[Test]
public void TemplateService_UpdateTemplate_ContentNameNotUnique_ServiceReturnsError()
{
Template Template = new Template()
{
TemplateId = 123,
};
// Arrange.
TemplateUpdateRequest request = new TemplateUpdateRequest()
{
ExistingTemplate = Template
};
var templateRepo = new Mock<ITemplateRepository>();
var uproduceRepo = new Mock<IUProduceRepository>();
templateRepo.Setup(p => p.IsUniqueTemplateItemName(215, 456, "Content", It.IsAny<string>())).Returns(false);
templateRepo.Setup(p => p.UpdateTemplate(request)).Returns(1);
// Act.
TemplateService svc = new TemplateService(templateRepo.Object, uproduceRepo.Object);
TemplateResponse response = svc.UpdateTemplate(request);
// Assert.
Assert.IsNotNull(response);
Assert.IsNotNull(response.data);
Assert.IsNull(response.Error);
}
So my issue is with this code:
TemplateService svc = new TemplateService(templateRepo.Object, uproduceRepo.Object);
Should the TemplateService really be newed up? What "if" the Service ended up hitting a database and/or file system? Then it becomes an integration test, and no longer a unit test, right?
TemplateResponse response = svc.UpdateTemplate(request);
Also, how do I really control whether this is truly going to pass or not? It is relying on a service call that I didn't write, so what if there is a bug, or encounters a problem, or return NULL, which is exactly what I do not want! ?
If you're testing TemplateService, then YES it should be newed up. How else can you test your actual implementation? The point here is to only test TemplateService and not it's dependencies (unless it's an integrations test).
So if you got a repo like IUProduceRepository it should be mocked, simply to ensure that you're not writing to some database, and to make sure that you can create a specific scenario.
Your goal is to test that TemplateService is doing the right thing, based on a specific scenario. So let's say that your IUProduceRepository is throwing an error that your TemplateServiceshould handle. Then you should mock that error in your IUProduceRepository and test your implementation of TemplateService and make sure that it handles it as expected.
So to answer your questions...
Should the TemplateService really be newed up? What "if" the Service
ended up hitting a database and/or file system? Then it becomes an
integration test, and no longer a unit test, right?
Yes, I would say that it would be an integrations test. You mock things to make sure that the service isn't writing to DB.
Also, how do I really control whether this is truly going to pass or
not? It is relying on a service call that I didn't write, so what if
there is a bug, or encounters a problem, or return NULL, which is
exactly what I do not want! ?
Your goal is to make sure that the class you test is doing what you expect in a specific scenario. Let's say that your repo is throwing an exception for some reason, then you might want to test that your service can handle that (or at least test that it's doing what's expected).
public class TemplateService : ITemplateService
{
ITemplateRepository _templateRepo;
IUProduceRepository _produceRepo
public TemplateService(ITemplateRepository templateRepo, IUProduceRepository produceRepo)
{
_templateRepo = templateRepo;
_produceRepo = produceRepo;
}
public TemplateResponse UpdateTemplate(Template template)
{
try
{
var result = _templateRepo.Update(template);
return result;
}
catch(Exception ex)
{
// If something went wrong. Always return null. (or whatever)
return null;
}
}
}
[Test]
public void TemplateService_UpdateTemplate_ShouldReturnNullOnError()
{
Template template = new Template() // note that I changed the variable name.
{
TemplateId = 123,
};
// Arrange.
TemplateUpdateRequest request = new TemplateUpdateRequest()
{
ExistingTemplate = template
};
var templateRepo = new Mock<ITemplateRepository>();
var uproduceRepo = new Mock<IUProduceRepository>();
// Mock exception
templateRepo.Setup(p => p.UpdateTemplate(request)).Throw(new ArgumentException("Something went wrong");
// Act.
TemplateService svc = new TemplateService(templateRepo.Object, uproduceRepo.Object);
TemplateResponse response = svc.UpdateTemplate(request);
// Assert.
// Make sure that the exception is handled and null is returned instead.
Assert.IsNull(response);
}
The ONLY thing you actually tested in the case above is that your service will return null if there's an error in your repo. That way, you have designed a test for a specific scenario, and made sure that your service is doing what's expected when that scenario occurs.
I know that you specifically mentioned that you didn't want it to return null, but it's more of the concept I'm talking about. So let's say that the repo returns null... Write a test for it. Mock the repo to return null, and then test that your service is doing what it should (logging, etc).
so what if there is a bug, or encounters a problem, or return NULL,
which is exactly what I do not want! ?
That's what unit testing is all about. Find a scenario, and then make sure that the class you're testing is doing it's part. Mock your dependencies to create that specific scenario.
When I write my tests I have a lot of tests that simply asserts that a method was called. Let's say that I have a service, which only responsibility is to call the repo. Then you might want to write three tests
Test that the service actually calls the repo.
Test that the service does what it's suppose to with the value from the repo.
Test what happens if the repo throws an exception.
A unit test is designed to test a unit of functionality, which often is (but definitely need not be) a single class (since we should follow the Single Responsibility Principle). Therefore, it's fine to new up the class(es) that you're trying to test - it's the dependencies that you need to mock/stub out, which in your case is what you've done with the two repositories.
Whether your call
TemplateResponse response = svc.UpdateTemplate(request);
ends up hitting the DB is a question of using Dependency Injection correctly - your team needs to be disciplined in using explicit dependencies (ie. the repositories which are constructor injected), and not newing up repositories within a class.
And regarding whether your test is going to pass or not - if the class only has explicit dependencies (which are mocked out in your test), then only the logic within the call will be tested, which is exactly what you want!
I recommend you to read the book The Art of Unit Testing: with examples in C# to learn good practice.
In your example, you are testing TemplateService class.
Your concern is what if TemplateService calls database. It depends on how this class is implemented. From the example and mock setup, I can understand that the details of ITemplateRepository is responsible for database calling and that is why UpdateTemplate and IsUniqueTemplateItemName are mocked.
If you want to avoid the Null check, then you can check whether the svc.UpdateTemplate(request) calls the method UpdateTemplate of ITemplateRepository with its parameter.
It should be similar as follows
templateRepo.Verify(u => u.UpdateTemplate(It.Is<TemplateUpdateRequest>(r => r.ExistingTemplate.TemplateId == 123)),Times.Once);
You can verify other method calls that you have mocked.
Interaction testing is a form of unit testing where you provide fake dependencies for everything (or some things, or only the really expensive things like databases or disks, there are a lot of different interpretations regarding this) except the thing you actually want to test.
In your example, you're testing whether the TemplateService code behaves correctly. The test provides fake collaborators (the repositories), which you can setup so they return different things in different tests. That way, you can verify whether the TemplateService behaves correctly under these circumstances.
If your concerns about new-ing up the TemplateService are that there might be some remaining calls to a real database in the TemplateService code itself, that's a design issue of the TemplateService code. Those calls should not happen in the TemplateService but should be implemented on a collaborating object (exactly so you can fake them in focused isolated tests for your service).
Writing a unit test without new-ing up the system-under-test provides zero value. If every object is a fake, how can you test your actual production code?
On your point about how those mocked services are actually implemented (Do they throw nulls? Any bugs? Do they return NULL?), that's a question you can solve by
a) Writing integration tests (warning: this does not scale well, see related reading on why integrated tests are a scam).
or b) using something J.B. Rainsberger calls "Contract tests" (see related reading below) to verify whether the actual collaborator objects actually behave in a way consumers expect them to do.
Related reading:
Classicist vs. mockist testing in Martin Fowlers Mocks Aren't Stubs.
Integrated tests are a scam by J.B. Rainsberger
Contract tests by J.B.Rainsberger Who tests the contract tests?

Having difficulties setting up a mock to unit test WebAPI Post

I'm attempting to set up a unit test with MSTest and Moq for a live system that posts json from a form to a database. The system itself works just fine, but I've been tasked with attempting to build some tests for it. The ajax call in the view I'm working with goes to following HttpPost method one of the controllers:
[HttpPost]
public ActionResult Add(Request model)
{
return ProcessRequest(model, UserAction.Create);
}
Which leads to the WebAPI controller:
public int Post([FromBody]Request value)
{
try
{
var id = myRepository.AddRequest(value);
foreach (var day in value.Days)
{
day.RequestId = id;
myRepository.AddRequestDay(day);
}
return id;
}
catch
{
return -1;
}
}
With my test, I thought that using TransactionScope would be a good idea so I'm not actually saving any data on the database. If there is a better approach, please enlighten me:
[TestMethod]
public void API_Request_Post()
{
using (TransactionScope ts = new TransactionScope())
{
var jsonObject = //some json scraped from a test post
var request = new Mock<HttpRequestBase>();
//This is where I'm stuck. I can't find anything in Setup that lets me prep the Post body for when the controller gets to it.
//request.Setup(x => x.InputStream).Returns(jsonObject);
RequestController controller = new RequestController();
//This is another point that I don't understand. I make the call for post happy with a reference to the model instead of the actual json?
var result = controller.Post(new Models.Request() );
Assert.IsTrue(result > -1);
}
}
Any help trying to determine what part of the HttpRequest I need to give my json to would be greatly appreciated (and helping me understand the Post would just be icing on the cake).
Aside
I hope I'm not telling you something you already know, but it looks like you are maybe questioning where to start? That is the hardest part of testing...
Just to make sure we are on the same page, the key to knowing what to test is describing the scenario, and the key to unit testing that scenario is Isolation.
What this means is you want to isolate in regard to the class "under test".
Also, code is much easier to test if you write the test first and then the code to make that pass. You're not in that situation, so that means that the code you have MAY NOT be testable without changing it.
And finally, given any external / 3rd party system, unless you are doing an "exploratory test" then you do not want to test 3rd party stuff, namely, http posting / getting. Instead, you want to test your code and how it performs.
Assuming you knew that or that all makes sense, then, this part will be be obvious too.
Moq, or any other mocking framework, is designed to stand in for objects / services that your class under test collaborates with, in order to aid in isolation. Given two classes, ClassA and ClassB, where ClassA acts on ClassB, you want to fake/mock Class B when giving it to ClassA so you can assert / verify that ClassA behaves as you would expect for the given scenario. This seems naive at first, but consider that you will also do the same for ClassB, you then have a suite of tests that isolate in respect to what they are testing, and that gives you great coverage.
And the key to isolation is injection, make sure that if ClassA acts on ClassB, you pass ClassB in to ClassA's constructor, that way you can give it a fake class B. Class B shouldn't do anything, other than respond how you say it should respond so you can prove that ClassA behaves appropriately in that situation.
Some people frown on changing code to make it testable, but my argument is if you wrote the code to be testable in the first place, you wouldn't have to change it, so try to refactor but not reengineer.
What to Test
So, what that means is you will want a few different scenarios, each with each tests that isolate in respect to what you care about.
The key to good tests is figuring out what it is you want to test, and then arranging your tests so that it is clear what you are doing.
Test Class Name DOES NOT need to have "Test" in it; that's redundant. Explain what the scenario is instead; who is involved, etc.
The Test Method should say what the action is that you care about testing; what states are you in, etc.
** Inside the method** for now follow the "Arrange, Act, Assert" (aka Given, When, Then) approach:
Arrange: set up all of your mocks or any variables you need here, including the one class you are testing, such as your real Controller but fake myRepository and fake value
Act: do the actual action, such as Post()
Assert: Prove that the behaviors you expected happened, such as when you give it a value with four days, then you expect that:
myRepository was told to add the value
myRepository was told to add a day four times
An Example
As I'm not entirely sure what the intent of the test is there, and I don't know all of the code, I'm going to give an example that I think will relate well and will hopefully also show how to set up the mocks (and ideally why you would!)
Also if this were truly a unit test, you would usually strive for one test per assertion / verification so you do not have to debug the test, only the failing code, but I'm putting three in here for "simplicity".
In this test, you'll see that I:
Care about testing the logic in POST
So I create a mocked repository that is only used for verification it was called,
And a mocked Request that is setup to respond appropriately when called,
And I pass the mocked repository to the Controller's constructor (isolation through injection)
And then I perform the action I care about, POST, on the live controller with mocked collaborators (repository and request),
And then I verify that POST performs / behaves as expected.
[TestClass]
public class GivenAValidRequestAndRepository(){
[TestMethod]
public void WhenWeReceiveAPostRequest(){
//Arrange / Given
var repository = new Mock<IRepository>();
var request = new Mock<IRequest>();
request.Setup ( rq => rq.ToString() )
.Returns ( "This is valid json ;-)" );
request.Setup ( rq => rq.Days )
.Returns ( new List<IDay> {
"Monday",
"Tuesday",
} );
var controller = new RequestController( repository.Object );
//Act / When
int actual = controller.Post( request.Object );
//Assert / Verify
// - then we add the request to the repository
repository.Verify(
repo => repo.AddRequest( request, Times.Once() );
// - then we add the two days (from above setup) in the request to the repository
repository.Verify(
repo => repo.AddRequestDays( It.IsAny<IDay>(), Times.Exactly( 2 ));
// - then we receive a count indicating we successfully processed the request
Assert.NotEqual( -1, actual );
}
}
Closing
Your goal should not be to make your boss happy that you have written a test. Instead, strive for valuable and expressive tests that you will be able to maintain down the road. You won't get it perfect (nor should you try) just make sure that what you are testing adds value. Cover things that if they were to change in code, your test would then fail, indicating you have a bug.
I hope this helps, please reply with comments / questions.

How to Moq NHibernate extension methods?

I'm developing an application using NHibernate for the ORM, NUnit for unit testing and Ninject for my DI. I'm mocking the ISession like so:
var session = new Mock<ISession>();
With the regular non-mocked session objects I can query them with LINQ extension methods like this:
var result = Session.Query<MyEntity>();
But when I try to mock this with the following code...
session.Setup(s => s.Query<MyEntity>());
...I get a runtime "Not supported" exception:
Expression references a method that does not belong to the mocked object: s => s.Query<MyEntity>()
How can I mock basic queries like this in Moq/NHibernate?
Query<T>() is an extension method, that's why you can't mock it.
Although #Roger answer is the way to go, sometimes it's useful to have specific tests. You can start investigating what Query<T>() method does - either by reading the NHibernate code, or using your own tests, and set the appropriate methods on ISession.
Warning: creating such a setup will make your test very fragile, and it will break, if the internal implementation of NHibernate changes.
Anyway, you can start your investigation with:
var mockSession = new Mock<ISession>(MockBehavior.Strict); //this will make the mock to throw on each invocation which is not setup
var entities = mockSession.Object.Query<MyEntity>();
The second line above is going to throw an exception and show you which actual property/method on ISession the Query<T>() extension method tries to access, so you can set it accordingly. Keep going that way, and eventually you will have a good setup for your session so you can use it in the test.
Note: I'm not familiar with NHibernate, but I have used the above approach when I had to deal with extension methods from other libraries.
UPDATE for version 5:
In the new NHibernate versions Query<T> is part of the ISession interface, not an extension function, so it should be easy to mock.
Old answer:
I tried Sunny's suggestion and got this far but got stuck since the IQuery is cast to an NHibernate.Impl.ExpressionQueryImpl which is internal and I don't think can be extended. Just posting this to save other lost souls a couple hours.
var sessionImplMock = new Mock<NHibernate.Engine.ISessionImplementor>(MockBehavior.Strict);
var factoryMock = new Mock<NHibernate.Engine.ISessionFactoryImplementor>(MockBehavior.Strict);
var queryMock = new Mock<IQuery>(MockBehavior.Strict);//ExpressionQueryImpl
sessionImplMock.Setup(x => x.Factory).Returns(factoryMock.Object);
sessionImplMock.Setup(x => x.CreateQuery(It.IsAny<IQueryExpression>())).Returns(queryMock.Object);
sessionMock.Setup(x => x.GetSessionImplementation()).Returns(sessionImplMock.Object);

Using Mock objects with Dictionary

I just started working with Unit Testing with NMock
I one my test cases involve adding an entry in a dictionary which is then passed to the unit being tested. I define the map as:
var item = new Mock<MyClass>().Object;
var myMap = new Dictionary<MyClass, IList<MyOtherClass>>
{
{ item, completionRequirement }
};
However when I do a myMap.ContainsKey(item) inside the unit being tested it returns false.
I am able to view a proxied item in the Dictionary on inspecting it. I am guessing that I need to do something else as well on the mocked item.(Most probably define .Equals(object o)).
My question is :
How do you define the Equals(object o) for the mocked item.
Or is there a different solution to the problem altogether.
You might want to mock the dictionary as well. That is, refactor to use IDictionary<MyClass,IList<MyOtherClass>, then pass in a mocked dictionary. You can then set up expectations so that it returns mocked objects as necessary.
It's also possible that you may not need to use a mock at all in this instance. It's not possible to tell from what you've given us, but I've often found that people new to mocking can sometimes forget that you can use the real objects as well if those objects don't have cascading dependencies. For example, you don't really need to mock a class that's just a simple container. Create one and use it, instead. Just something to think about.
The approach given at http://richardashworth.blogspot.com/2011/12/using-reflection-to-create-mock-objects.html is in Java, but presents another approach to this problem using Reflection.
I like the idea of setting up a 'fake' object along the lines of what tvanfosson is suggesting.
But if you want to do it with a mocking framework, I think all you need to do is setup an expectation for what item.Object should be. In Rhino Mocks the syntax would be something like:
var knownObject = "myKey";
var mock = MockRepository.GenerateStub<IMyClass>();
mock.Stub(x=>x.Object).Return(knownObject);
That said, I have no idea what the equivalent code would be in NMocks, but it shouldn't be hard to figure it out if you're working with it (you can always ask a question on the user group).
HTH

Categories