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
Related
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.
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);
I'm using Code First to map classes to an existing database. I need a way to unit test these mappings, which are a mix of convention-based, attribute-based, and fluent-api.
To unit test, I need to confirm that properties of the classes map to the correct table and column names in the database. This test needs to be performed against the context, and should cover all configuration options for code first.
At a very high level, I'd be looking to assert something like (pseudo-code):
Assert.IsTrue(context.TableFor<Widget>().IsNamed("tbl_Widget"));
Assert.IsTrue(context.ColumnFor<Widget>(w => w.Property).IsNamed("WidgetProperty"));
Another idea to consider is using Linq and ToString().
For eaxample this :
context.Widget.Select(c => c.Property).ToString()
Will result in this for SQL Server Provider :
"SELECT [Var_3].[WidgetProperty] AS [WidgetProperty] FROM [dbo].[Widget]..."
Now we could hide it all in some Extension method that and parses resulting SQL it would look almost like Your pseudo-code :
Assert.IsTrue(context.Widgets.GetSqlColumnNameFor(w => w.Property).IsNamed("WidgetProperty"));
Draft for extension :
public string GetSqlColumnNameFor<TSource>(this DbSet<T> source, Expression<Func<TSource, TResult>> selector)
{
var sql = source.Select(selector).ToString();
var columnName = sql... // TODO : Some regex parsing
return
columnName;
}
Similary we could create GetSqlTableNameFor().
UPDATE : I decided to look for some dedicates SQL Parsers, so this solution is more generic, obviously there is such a thing for .NET :
http://www.dpriver.com/blog/list-of-demos-illustrate-how-to-use-general-sql-parser/generate-internal-query-parse-tree-in-xml-for-further-processing/
The only way I can think of to cover every possible option would be to use the Entity Framework Power Tools to pre-compile the views of your DbContext, and probably use a combination of reflection on that generated type and RegEx on the generated code itself to verify everything maps the way you want it to. Sounds pretty painful to me.
Another thing that comes to mind is creating a facade around DbModelBuilder to intercept and check everything that passes through it, but I don't know if that would handle the convention-based stuff. Also sounds painful.
As a less-complete, but much easier alternative, you can probably knock out a large portion of this by switching to attribute-based mapping wherever possible. This would allow you to create a base test class, say, ModelTesting<TEntity>, which includes a few test methods that use reflection to verify that TEntity has:
A single TableAttribute.
Each property has a single ColumnAttribute or NotMappedAttribute.
At least one property with a KeyAttribute.
Each property type maps to a compatible database type.
You could even go so far as to enforce a naming convention based on the names of the properties and class (with a caveat for table-per-hierarchy types). It would also be possible to check the foreign key mappings as well. That's a write-once base class you can derive from once for each of your model types and catch the majority of your mistakes (well, it catches the majority of mine, anyway).
Anything that can't be represented by attributes, like TPH inheritance and such, becomes a little harder. An integration test that fires up the DbContext and does a FirstOrDefault on Set<TEntity>() would probably cover most of those bases, assuming your DbContext isn't generating your database for you.
If you wrote a method
public static string ToMappingString(this Widget obj)
Then you could easily testing this via approval tests ( www.approvaltests.com or nuget)
There's a video here: http://www.youtube.com/watch?v=vKLUycNLhgc
However, if you are looking to test "My objects save and retrive themselves"
Then this is a perfect place of "Theory Based Testing"
Theory based testing
Most unit test take the form of
Given A,B expect C
Theory based testing is
Given A,B expect Theory
The beauty of this is there is no need to worry about which particular form A & B take since you don't need to know C, so any random generator will work.
Example 1: Testing Add and Subtract methods
Normally you would have stuff like
Assert.AreEqual(5, Add(2,3));
Assert.AreEqual(9, Add(10,-1));
Assert.AreEqual(10, Add(5,5));
Assert.AreEqual(7, Subtract(10,3));
However if you wrote a Theory Test it would look like
for(int i = 1; i < 100; i++)
{
int a = random.Next();
int b = random.Next();
Assert.AreEqual(a, Subtract(Add(a,b),b, string.Format("Failed for [a,b] = [{0},{1}], a,b));
}
Now that you understand Theory based testing, the theory you are trying to test is
Given Model A
When A is stored to the database, and retrieved the resulting object is equal to A
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.
I'm trying to grasp test driven development, and I'm wondering if those unit tests is fine. I have a interface which looks like this:
public interface IEntryRepository
{
IEnumerable<Entry> FetchAll();
Entry Fetch(int id);
void Add(Entry entry);
void Delete(Entry entry);
}
And then this class which implements that interface:
public class EntryRepository : IEntryRepository
{
public List<Entry> Entries {get; set; }
public EntryRepository()
{
Entries = new List<Entry>();
}
public IEnumerable<Entry> FetchAll()
{
throw new NotImplementedException();
}
public Entry Fetch(int id)
{
return Entries.SingleOrDefault(e => e.ID == id);
}
public void Add(Entry entry)
{
Entries.Add(entry);
}
public void Delete(Entry entry)
{
Entries.Remove(entry);
}
}
Theese are the unit tests I have written so far, are they fine or should I do something different? Should i be mocking the EntryRepository?
[TestClass]
public class EntryRepositoryTests
{
private EntryRepository rep;
public EntryRepositoryTests()
{
rep = new EntryRepository();
}
[TestMethod]
public void TestAddEntry()
{
Entry e = new Entry { ID = 1, Date = DateTime.Now, Task = "Testing" };
rep.Add(e);
Assert.AreEqual(1, rep.Entries.Count, "Add entry failed");
}
[TestMethod]
public void TestRemoveEntry()
{
Entry e = new Entry { ID = 1, Date = DateTime.Now, Task = "Testing" };
rep.Add(e);
rep.Delete(e);
Assert.AreEqual(null, rep.Entries.SingleOrDefault(i => i.ID == 1), "Delete entry failed");
}
[TestMethod]
public void TestFetchEntry()
{
Entry e = new Entry { ID = 2, Date = DateTime.Now, Task = "Testing" };
rep.Add(e);
Assert.AreEqual(2, rep.Fetch(2).ID, "Fetch entry failed");
}
}
Thanks!
Just off the top of my head...
Although your testing of add really only tests the framework:
You've got adding 1 item, that's good
what about adding LOTS of items
(I mean, ridiculous amounts - for what value of n entries does the container add fail?)
what about adding no items? (null entry)
if you add items to the list, are they in a particular order?
should they be?
likewise with your fetch:
what happens in your fetch(x) if x > rep.Count ?
what happens if x < 0?
what happens if the rep is empty?
does x match performance requirements (what's it's algorithmic
complexity? is it within range when there's just one entry and when
there's a ridiculously large amount of entries?
There's a good checklist in the book Pragmatic Unit Testing (good book, highly recommended)
Are the results right?
Are all the boundary conditions CORRECT
Conform to an expected format
Ordered correctly
In a reasonable range
Does it Reference any external dependencies
Is the Cardinality correct? (right number of values)
does it complete in the correct amount of Time (real or relative)
Can you check inverse relationships
Can you cross check the results with another proven method
Can you force error conditions
Are performance characteristics within bounds
Here's some thoughts:
Positive
You're Unit Testing!
You're following the convention Arrange, Act, Assert
Negative
Where's the test to remove an entry when there's no entry?
Where's the test to fetch an entry when there's no entry?
What is supposed to happen when you add two entries and remove one? Which one should be left?
Should Entries be public. The fact that one of your asserts calls rep.Entries.SingleOrDefault suggests to me you're not constructing the class correctly.
Your test naming is a bit vague; typically a good pattern to follow is: {MethodName}_{Context}_{Expected Behavior} that remove the redundancy "test" redundancy.
As a beginner to TDD I found the book Test-Driven Development By Example to be a huge help. Second, Roy Osherove has some good Test Review video tutorials, check those out.
Before I answer, let me state that I am fairly new to unit testing and by no means an expert, so take everything I state with a grain of salt.
But I feel that your unit tests are largely redundant. Many of your methods are simple pass through, like your AddEntry method is simply a call to the underlying List method Add. Your not testing your code, your testing the Java library.
I would recommend only unit testing methods that contain logic that you write. Avoid testing obvious methods like getters and setters, because they operate at the most basic level. That's my philosophy, but I know some people do believe in testing obvious methods, I just happen to think it is pointless.
Seems fine like this. I personally like to give my tests a bit more descriptive names but that's more of a personal preference.
You can use mocking for dependencies of the class you're testing, EntryRepository is the class under test so no need to mock that, else you would end up testing the mock implementation instead of the class.
Just to give a quick example. If your EntryRepository would use a backend database to store the Entries instead of a List you could inject a mock-implementation for the data-access stuff instead of calling a real database.
This looks like a fine start, but you should try to test the 'borderline' cases as much as possible. Think about what might cause your methods to fail - Would passing a null Entry to Add or Delete be valid? Try to write tests that exercise every possible code path. Writing tests in this manner will make your test suite more useful in the future, should you make any changes to the code.
Also, it is useful for each test method to leave the test object in the same state as when it was invoked. I noticed your TestFetchEntry method adds an element to the EntryRepository, but never removes it. Having each method not affect test object state makes it easier to run series of tests.
You should not be mocking the IEntryRepository since the implementing class is the class under test. You might want to mock the List<Entry> and inject it, then just test that the methods that you invoke via your public interface are called appropriately. This would just be an alternative to the way you have it implemented and isn't necessarily better -- unless you want the class to have it's backing class injected in which case writing the tests that way would force that behavior.
You might want some more tests to make sure that when you insert an entry, the right entry is inserted. Likewise with delete -- insert a couple of entries, then delete one and make sure that the proper one has been deleted. Once you come up with tests to get the code to do what you want it to, keep thinking of ways that you could mess up writing the code and write tests to make sure those don't happen. Granted this class is pretty simple and you may be able to convince yourself that the tests you have that drive behavior is sufficient. It doesn't take much complexity, though, to make it worth testing edge cases and unexpected behavior.
For a TDD beginner and for this particular class, your tests are fine. +1 for making the effort.
Post another question once you get to more complex scenarios involving dependency injection and mocking. This is where things get really interesting ;).
Looks good overall. You should use transactions (or create new instance of repository in TestInitialize) to make sure the tests are trully isolated.
Also use more descriptive test methods, like When_a_new_entity_is_added_to_a_EntryRepository_the_total_count_of_objects_should_get_incremented