Unit testing classes with mocked repository dependecies - c#

I have a service class with several methods. Service has some dependencies on repositories. I am using Moq to mock the repository. I have a problem with the proper unit testing one of the methods. I will give you an example:
public interface IRepository<T>
{
IEnumerable<T> FindAll();
IEnumerable<T> FindByQuery(Predicate<T> predicate);
//many other methods for retreiving T's
}
public class MyService
{
private readonly IRepository<Category> _repo;
public MyService(IRepository<Category> repo)
{
_repo = repo;
}
public List<Category> FindActiveCategories()
{
return _repo.FindAll().Where(x => x.Active).ToList();
}
}
Now, I wrote a unit test:
public FindActiveCategories_WhenCalled_ShouldReturnActiveCategories() {
var moq = new Mock<IRepository<Category>>();
var list = new List<Category>
{
new Category {Active = true},
new Category {Active = false}
};
moq.Setup(x => x.FindAll()).Returns(list);
var service = new MyService(moq.Object);
var result = service.FindActiveCategories();
Assert.IsTrue(result.All(x=>x.Active));
}
And the test of course passed. But than I realized that I retreived all the Categories in my service method using FindAll - it was an obvious thing to correct, because I didn't want to load several thousands of categories to memory just to pull out only few of them. So I changed the implementation of FindActiveCategories method to this:
public List<Category> FindActiveCategories()
{
return _repo.FindByQuery(x => x.Active).ToList();
}
And my test failed this time. The problems is obvious - the test depended on the implementation details. I knew that the FindActiveCategories method uses FindAll method of the repository, so I wrote a setup for this method. After changing the implementation I have to change the implementation of the test method - this seems to be a problem. Of course I could've setup all the Find... methods but there are plenty of them in the repository and one can choose many of them, this also doesn't seem right approach for me. Not to mention TDD - if I was trying to write the test first, I wouldn't know what and how to mock the repository interface. My question is: what is a correct way to handle this kind of dependencies to be able to write implementation independent unit tests.

Despite the title of this question, the actual question here seems to be "should I need to change my test if my code implementation changes?"
The answer to that is that if the implementation is entirely contained within your code under test then 'no'. For example, if I have a method to multiply two values and I implement it the obvious way, I can write tests to prove that it works. Now if I change the implementation to do the calculation using a for loop and accumulating a total within the loop, all of my tests should pass with no changes.
The problem is that most of the code we write isn't like that: it depends on other things. If the code under test depends on other things we have two choices: do an integration test, or mock the dependency.
The integration test supplies the class under test with the real dependencies that it would be using when actually in use. This is the most valuable testing, since it is completely realistic. The answer here would also be 'no need to change the test if you change the implementation'. However, this is often impractical, since it exponentially increases the cost of writing and maintaining the tests.
Mocking requires you to specify how the dependency should behave, so by definition, your test must know what the code under test is going to use, and how. Therefore if you change the implementation, you should reasonably expect to have to change the test, so the answer would be 'yes'.
However, consider this point. The parts of your test which do not relate to mocking should not need to change. You aren't using the Arrange Act Assert pattern (which can help make tests more readable, particularly when mocking); but the Act and Assert parts, which would be the last two lines of your test, should not need to change. Maybe that will allow you to believe you're still doing TDD.
But don't lose sleep over it: there are other things which would benefit from your attention more. For example, change the implementation of your method to...
public List<Category> FindActiveCategories()
{
return new List<Category>();
}
... then the test will pass, even though the code won't do what you want (because the All in the assert returns true for an empty list).
Hope this was useful.

The following will work for the change made above.
[TestClass]
public class MyServiceShould {
[TestMethod]
public void FindActiveCategories_WhenCalled_ShouldReturnActiveCategories() {
//Arrange
var moq = new Mock<IRepository<Category>>();
var list = new List<Category> {
new Category {Active = true},
new Category {Active = false}
};
moq
.Setup(x => x.FindByQuery(It.IsAny<Predicate<Category>>()))
.Returns((Predicate<Category> predicate) => list.Where(x => predicate(x)));
var service = new MyService(moq.Object);
//Act
var result = service.FindActiveCategories();
//Assert
Assert.IsTrue(result.All(x => x.Active));
}
}
The mock takes the passed predicate and applies it to the fake collection in order to allow the test to be exercised to completion.
Reference Moq Quickstart to get a better understanding of how to use the mocking framework.

Related

Nested required objects [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am attempting to write a unit test and am having an issue where each mocked object relies on another 3 objects. This looks something like this.
var objC = new Mock<IObjectC>(IObjectG, IObjectH);
var objB = new Mock<IObjectB>(IObjectE, IObjectF);
var objA = new Mock<IObjectA>(IObjectB, IObjectC, IObjectD);
What am I doing wrong?
What am I doing wrong?
You are violating Law of Demeter and creating system with the tight coupling of components. If you would stick to this law and make a method that only invokes members of:
The object itself.
An argument of the method.
Any object created within the method.
Any direct properties/fields of the object.
then you would not have the problem of complex test setup.
BEFORE: consider ATM class which talks to client's wallet:
public void ProcessPayment(Person client, decimal amount)
{
var wallet = client.Wallet;
if (wallet.TotalAmount() < amount)
throw new BlahBlahException();
wallet.Remove(amount);
}
with complex setup of
[Test]
public void AtmShouldChargeClientWhenItHasEnoughMoney()
{
var walletMock = new Mock<IWallet>();
walletMock.Setup(w => w.GetTotalAmount()).Returns(15);
var personMock = new Mock<Person>(walletMock.Object);
var atm = new Atm();
atm.ProcessPayment(personMock.Object, 10);
walletMock.Verify(w => w.Remove(10), Times.Once);
}
AFTER: Consider now method which talks only to members of its arguments (Law of Demeter #2)
public void ProcessPayment(IClient client, decimal amount)
{
if (!client.TryCharge(amount))
throw new BlahBlahException();
}
Not only code becomes simple and readable, but also test setup is simplified:
[Test]
public void AtmShouldChargeClientWhenItHasEnoughMoney()
{
var clientMock = new Mock<IClient>();
clientMock.Setup(c => c.TryCharge(10)).Returns(true);
var atm = new Atm();
atm.ProcessPayment(clientMock.Object, 10);
clientMock.VerifyAll();
}
Note that there is no real classes involed anymore. We replaced Person dependency with abstract IClient dependency. If something will be broken in Person implementation, it will not affect ATM tests.
Of course, you should have separate test for Person class to check if it correctly interacts with wallet:
[Test]
public void PersonShouldNotBeChargedWhenThereIsNotEnoughMoneyInWallet()
{
var walletMock = new Mock<IWallet>(MockBehavior.Strict);
walletMock.Setup(w => w.GetTotalAmount()).Returns(5);
var person = new Person(walletMock.Object);
person.TryCharge(10).Should().BeFalse();
walletMock.VerifyAll();
}
[Test]
public void PersonShouldBeChargedWhenThereIsEnoughMoneyInWallet()
{
var walletMock = new Mock<IWallet>(MockBehavior.Strict);
walletMock.Setup(w => w.GetTotalAmount()).Returns(15);
walletMock.Setup(w => w.Remove(10));
var person = new Person(walletMock.Object);
person.TryCharge(10).Should().BeTrue();
walletMock.VerifyAll();
}
Benefits - you can change implementation of Person class without breaking ATM functionality and tests. E.g. you can switch from wallet to credit cards, or check credit cards if wallet is empty.
The purpose of mocking types is so we can write tests without having to deal with complex dependency graphs, or having to worry about communicating with any external processes, so we can focus on writing fast, deterministic unit tests. What that means is when you create a mock, the internal representation of that mock is of no concern to your tests; it's simply a proxy object that replaces a real implementation that your code would use in production.
That said, we still need to be able to configure those mocks to exhibit the behaviour we desire - for example, returning values, or throwing exceptions - which is why we can configure setups on them with calls to Setup().
Now, going back to your question, I'm wondering if what you're really describing is the situation where you want to call a mock to return another mock. That can happen in scenarios such as wanting to return a mocked strategy from a mocked factory. To do that, you'd have to setup the factory to return the strategy. Something like this:
var factoryMock = new Mock<IFactory>();
var strategyMock = new Mock<IStrategy>();
var type = typeof(FakeConcreteStrategy);
factoryMock.Setup(x => x.Create(type)).Returns(strategyMock.Object);
With the above, a call to the factory's Create method with a type of FakeConcreteStrategy will return the mocked strategy. From there, you could do whatever you needed with the strategy, such as verifying a call to it:
strategyMock.Verify(x => x.DoWork(), Times.Once);
This might point to a flaw in the design of the code you're testing. That's not bad - that's a good thing. It might not be - the problem could be what you're trying to accomplish with the test.
If you're mocking IObjectA, why do you need to mock its dependencies? If the class you're testing depends on IObjectA, should it matter whether implementations of IObjectA have their own dependencies? One benefit of depending on an abstraction is that a class doesn't have to be concerned with the implementation details of its dependencies. In other words, all your class should care about is what IObjectA does. It shouldn't know or care if IObjectA even has dependencies, let alone what they do.
If your class "knows" that IObjectA represents a class with its own dependencies, then it's really depending on more than the interface. The problem might indicate that you should refactor your class so that it only depends on the interface, not the dependencies of classes that implement the interface.
If IObjectA has properties or methods that need to return implementations of other interfaces then you could create mocks for those interfaces, and then configure your mock of IObjectA to return those mocks.

Mocking a Linq2Sql DataContext

I have a Lin2Sql DataContext that I am using to get all my data from a sql database however I am struggling to find a way to successfully Mock this so that I can create relevant Unit Tests.
In my data access objects that I am wanting to test I am refreshing the context each time and I am finding it difficult to find a simple suitable way to mock this.
Any help with this matter will be greatly appreciated.
Mocking the linq-to-sql context is indeed a huge task. I usually work around it by letting my unit tests run against a separate database copy, with data specially crafted to fit the unit tests. (I know it can be argued that it's no longer unit tests, but rather integration tests, but I don't care as long as I get the code tested).
To keep the database in a known state I wrap each test in a TransactionScope which is rolled back at the end of the test. That way the state of the database is never changed.
A sample test method looks like this:
[TestMethod]
public void TestRetire()
{
using (TransactionScope transaction = new TransactionScope())
{
Assert.IsTrue(Car.Retire("VLV100"));
Assert.IsFalse(Car.Retire("VLV100"));
// Deliberately not commiting transaction.
}
}
The code is from a blog post about the method I wrote some time ago: http://coding.abel.nu/2011/12/using-transactions-for-unit-tests/
Since you request a way to mock a DataContext I assume that you really want to do some unit tests and not integration tests.
Well, I will tell you how to accomplish this, but first I would like to encourage you to read the following links, they are all about writing clean testable code.
http://misko.hevery.com/code-reviewers-guide/
http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
And check the links from this response:
https://stackoverflow.com/a/10359288/1268570
Watch the clean code talks from Misko Hevery (given to the Google people)
http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded
http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded
http://www.youtube.com/watch?v=-FRm3VPhseI&feature=player_embedded
http://www.youtube.com/watch?v=4F72VULWFvc&feature=player_embedded
One thing that I used to repeat to myself and to my fellows at work, is that anyone can write a unit test, because they are silly easy to write. So a simple test is essentially all about making some comparisons and throw exceptions if the results fails, anyone can do that. Of course, there are hundreds of frameworks to help us write those tests in an elegant way. But the real deal, and the real effort shroud be put on learn how to write clean testable code
Even if you hire Misko Hevery to help you write tests, he will have a real hard time writing them if your code is not test-friendly.
Now the way to mock a DataContext objects is: do not do it
Instead wrap the calls using a custom interface instead:
public interface IMyDataContextCalls
{
void Save();
IEnumerable<Product> GetOrders();
}
// this will be your DataContext wrapper
// this wll act as your domain repository
public class MyDataContextCalls : IMyDataContextCalls
{
public MyDataContextCalls(DataClasses1DataContext context)
{
this.Context = context;
}
public void Save()
{
this.Context.SubmitChanges();
}
public IEnumerable<Product> GetOrders()
{
// place here your query logic
return this.Context.Products.AsEnumerable();
}
private DataClasses1DataContext Context { get; set; }
}
// this will be your domain object
// this object will call your repository wrapping the DataContext
public class MyCommand
{
private IMyDataContextCalls myDataContext;
public MyCommand(IMyDataContextCalls myDataContext)
{
this.myDataContext = myDataContext;
}
public bool myDomainRule = true;
// assume this will be the SUT (Subject Under Test)
public void Save()
{
// some business logic
// this logic will be tested
if (this.myDomainRule == true)
{
this.myDataContext.Save();
}
else
{
// handle your domain validation errors
throw new InvalidOperationException();
}
}
}
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
// in this test your mission is to test the logic inside the
// MyCommand.Save method
// create the mock, you could use a framework to auto mock it
// or create one manually
// manual example:
var m = new MyCommand(new MyFakeDataContextFake());
m.Invoking(x => x.Save())
//add here more asserts, maybe asserting that the internal
// state of your domain object was changed
// your focus is to test the logic of the domain object
.ShouldNotThrow();
//auto mock example:
var fix = new Fixture().Customize(new AutoMoqCustomization());
var sut = fix.CreateAnonymous<MyCommand>();
sut.myDomainRule = false;
sut.Invoking(x => x.Save())
.ShouldThrow<InvalidOperationException>();
}
public class MyFakeDataContextFake : IMyDataContextCalls
{
public void Save()
{
// do nothing, since you do not care in the logic of this method,
// remember your goal is to test the domain object logic
}
public IEnumerable<Product> GetOrders()
{
// we do not care on this right now because we are testing only the save method
throw new NotImplementedException();
}
}
}
Notes:
When you declare your IMyDataContextCalls interface you are actually abstracting the use of a DataContext, therefore this interface should contain only POCO objects (most of the time), if you follow this approach your interfaces will be decoupled from any undesired dependency.
In the specific MyDataContextCalls implementation, you are explicitly using a DataClasses1DataContext context, but you are free to change the implementation at any time and that won't affect your external code, and that's because you are always working with the IMyDataContextCalls interface instead. So at any time you could change for example this implementation for another one using the wonderful NHibernate =) or the poor ef or a mock one
At last, but not least. please double check my code, and you will notice that there are no new operators in the domain objects. This is a rule of dumb when writing test friendly code: decouple the responsibility of creating objects outside of your domain objects
I personally use three frameworks on every project and on every test I write, I really recommend them:
AutoFixture
Moq
FluentAssertions
For example, in the code above, I showed you how to write a manual fake for your repository, but that clearly is something we do not want to do in a real project, imagine the number of objects you would have to code in order to write your tests.
Instead use the power of AutoFixture combined with Moq:
This line: var m = new MyCommand(new MyFakeDataContextFake());
Will become:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var sut = fixture.CreateAnonymous<MyCommand>();
And that's it, this code will automatically create mocks for all the objects needed in the constructor of MyCommand.
In short, you don't mock DataContext. You extract interface from it and mock that interface using some collections for entity sets, and then verify contents of those collections.

How to use mocks in this case?

Here is my problem:
I have an n-tiers application for which I have to write unit tests. Unit tests are for the business layer.
I have a method to test called Insert() and this one use two protected methods from inheritance and call directly a method from Data access layer.
So I have made a mock object for the DAL. But here is the point, in a (edit :) protected method from inheritance, It will use another object from DAL! It seems it is not possible to mock this one!
Here is the method for test code:
public int Insert(MYOBJECT aMyObject)
{
//first inherited method use the FIRSTDALOBJECT so the mock object --> No problem
aMyObject.SomeField= FirstInherited();
//Second inherited method (see after) --> my problem
aMyObject.SomeOtherField = SecondInherited();
// Direct access to DALMethod, use FIRSTDALOBJECT so the mock -->No Problem
return this.FIRSTDALOBJECT.Insert(aMyObject);
}
Here is the SecondInherited method:
protected string SecondInherited ()
{
// Here is my problem, the mock here seems not be possible for seconddalobject
return ( new SECONDDALOBJECT Sdo().Stuff());
}
And here is the unit test method code :
[TestMethod()]
public void InsertTest()
{
BLLCLASS_Accessor target = new BLLCLASS_Accessor();
MYOBJECT aMyObject = new MYOBJECT { SomeField = null, SomeOtherField = 1 };
int expected = 1;
int actual;
//mock
var Mock = new Mock<DAL.INTERFACES.IFIRSTDALOBJECT>();
//Rec for calls
List<SOMECLASS> retour = new List<SOMECLASS>();
retour.Add(new SOMECLASS());
//Here is the second call (last from method to test)
Mock
.Setup(p => p.Insert(aMyObject))
.Returns(1);
// Here is the first call (from the FirstInherited())
Mock
.Setup(p => p.GetLast())
.Returns(50);
// Replace the real by the mock
target.demande_provider = Mock.Object;
actual = target.Insert(aMyObject);
Assert.AreEqual(/*Some assertion stuff*/);
}
Thank you for reading all the question :-) Hope it is clear enough.
Your text seems to say that SecondInherited is private, while in the code example it is protected. Anyway, if it is not protected, I would suggest changing its access qualifier as the first step.
You can create a subclass solely for testing purposes, and override SecondInherited there to avoid creating SECONDDALOBJECT and just return some value suitable for your tests.
This way you can write your first unit test(s) with minimal changes to the class being tested, thus minimizing the chances of breaking something. Once you have the unit tests in place, these allow you to do more refactoring safely, eventually achieving a better (more testable / mockable) design, such as using Dependency Injection, or a Factory. (I would probably prefer an Abstract Factory over Factory Method here, as the latter would practically force you to keep subclassing the tested class).
The fundamental, highly recommended book for learning this technique (and many more) is Working Effectively With Legacy Code.
No chance to mock this with MOQ.
You have two options:
Use TypeMock or Moles to mock the SECONDDALOBJECT class
Refactor the code, so the instance of SECONDDALOBJECT isn't created in the way it is, but in a way that can be mocked (Factory method, DI, ...) (prefered!)

Unit Testing practice with Linq to SQL

I'm trying to wrap my head around unit testing, and I've encountered a behavior that I'm unsure of:
"Can Backup Inventory"
Basically, the "Inventory" table is copied to the "InventoryHistory" table, and given a time-stamp of when the backup occurred ("HistoryDate").
Here's the code for backing-up inventory:
DateTime historyDate = DateTime.Now;
MyDataContext db = new MyDataContext();
db.GetTable<InventoryHistory>().InsertAllOnSubmit(
db.GetTable<Inventory>()
.Select(i => new InventoryHistory
{
ID = i.ID,
ItemName = i.ItemName,
/* etc, etc, etc */
HistoryDate = historyDate
})
);
My questions are:
Should/Can this behavior be broken down into smaller unit-testable parts?
Since I am testing against a dedicated test database, should I be using a mocking tool and following the abstract factory pattern for any "repositories"?
The question I would ask is that is this really a unit test? A unit test would consider mocked Table<TEntity> instances, because we're not concerned with the actual data, rather that the mechanism of creating the items is correct.
In your snippet above, it seems that you are unit testing the Linq methods themselves, not any specific code you have written yourself.
As for your last question, one of the fundamental mistakes made with mocking is the assumption of what to test when mocking. Typically you would be mocking a something consumed by the type you want to test. E.g.:
public ICalculatorService
{
int Add(int a, int b);
}
[Test]
public void CannAdd()
{
var mock = Mock<ICalculatorService();
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(100);
var service = mock.Object;
Assert(service.Add(1, 2) == 100); // Incorrect
}
The above is a pointless test, because I am testing that it is returning exactly what I have told it to. I'm not testing the Moq framework here, I need to test my code, so I would need to be testing the consumer:
public class Calculator
{
private readonly ICalculatorService _service;
public Calculator(ICalculatorService service)
{
_service = service;
}
public int Add(int a, int b)
{
return _service.Add(a, b);
}
}
[Test]
public void CannAdd()
{
var mock = Mock<ICalculatorService();
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(100);
var calculator = new Calculator(mock.Object);
Assert(calculator.Add(1, 2) == 100); // Correct
}
That's more like it (although a simplistic example). I am now testing the Calculator consumer itself, not the consumable. In your example, even if you were mocking your DataContext to return dummy instances of Table<TEntity>, what real benefits do you get?
Realistically you'd probably create a repository, e.g. an IInventoryRepository, and create a consumer of that repository (could be a domain model, a controller, etc). Then through testing, you'd mock that repository, and test your consumer.
This looks like a fairly atomic operation to me, not much opportunity for breaking it apart.
Unit testing does not hit the database- that's integration testing. If you want a good unit test for this, you would test for behavior- in this case, that the history is backed up when it's supposed to be.
By way of full disclosure, I'm only just starting to learn EF and LINQ and the best way to test them, so you may get some more useful information regarding them in particular, so these are just general testing answers.
1.
I can't see a way that this can be further broken down to be isolated for unit testing, apart from:
ID = i.ID,
ItemName = i.ItemName,
/* etc, etc, etc */
HistoryDate = historyDate
being refactored into a seperate method to be unit tested as the only other code are LINQ calls, which MS are responsible for testing.
2.
I don't think you'd be able to introduce a seam to isolate it with the abstract repository factory pattern, since you're calling into a datacontext.
I'm not sure whether you should fake this (and since you'd be testing against it will be a mock proper - a fake that you test against, a fake that you don't test against is a stub) but since it's calling into a test server, you can make it an automated integration test since the functionality involves the interaction with the data store.
At first, method you describe looks simply and I'm not sure it needs any unit tests.
But, if you want to decompose it, you may do this:
Extract method for getting list of inventories for backup
IQueryable GetInventoryForBackup(this DataContext context)
{
return context.GetTable();
}
Extract method to convert Inventory to InventoryHistory
IEnumerable ToInventoryHistory(this IEnumerable data, DateTime historyDate)
{
return data.Select(i => new InventoryHistroy { ID = i.Id ....
}
Extract method to save sequence of InventoryHistory
void SaveHistory(IEnumerable data)
{
dataContext.InsertAllOnSubmit(data);
dataContext.SubmitChanges();
}
Now you have seemsful methods and you can easy write unit tests for.

How to handle setting up complex unit test and have them only test the unit

I have a method that takes 5 parameters. This method is used to take a bunch of gathered information and send it to my server.
I am writing a unit test for this method, but I am hitting a bit of a snag. Several of the parameters are Lists<> of classes that take some doing to setup correctly. I have methods that set them up correctly in other units (production code units). But if I call those then I am kind of breaking the whole idea of a unit test (to only hit one "unit").
So.... what do I do? Do I duplicate the code that sets up these objects in my Test Project (in a helper method) or do I start calling production code to setup these objects?
Here is hypothetical example to try and make this clearer:
File: UserDemographics.cs
class UserDemographics
{
// A bunch of user demographic here
// and values that get set as a user gets added to a group.
}
File: UserGroups.cs
class UserGroups
{
// A bunch of variables that change based on
// the demographics of the users put into them.
public AddUserDemographicsToGroup(UserDemographcis userDemographics)
{}
}
File: UserSetupEvent.cs
class UserSetupEvent
{
// An event to record the registering of a user
// Is highly dependant on UserDemographics and semi dependant on UserGroups
public SetupUserEvent(List<UserDemographics> userDemographics,
List<UserGroup> userGroups)
{}
}
file: Communications.cs
class Communications
{
public SendUserInfoToServer(SendingEvent sendingEvent,
List<UserDemographics> userDemographics,
List<UserGroup> userGroups,
List<UserSetupEvent> userSetupEvents)
{}
}
So the question is: To unit test SendUserInfoToServer should I duplicate SetupUserEvent and AddUserDemographicsToGroup in my test project, or should I just call them to help me setup some "real" parameters?
You need test duplicates.
You're correct that unit tests should not call out to other methods, so you need to "fake" the dependencies. This can be done one of two ways:
Manually written test duplicates
Mocking
Test duplicates allow you to isolate your method under test from its dependencies.
I use Moq for mocking. Your unit test should send in "dummy" parameter values, or statically defined values you can use to test control flow:
public class MyTestObject
{
public List<Thingie> GetTestThingies()
{
yield return new Thingie() {id = 1};
yield return new Thingie() {id = 2};
yield return new Thingie() {id = 3};
}
}
If the method calls out to any other classes/methods, use mocks (aka "fakes"). Mocks are dynamically-generated objects based on virtual methods or interfaces:
Mock<IRepository> repMock = new Mock<IRepository>();
MyPage obj = new MyPage() //let's pretend this is ASP.NET
obj.IRepository = repMock.Object;
repMock.Setup(r => r.FindById(1)).Returns(MyTestObject.GetThingies().First());
var thingie = MyPage.GetThingie(1);
The Mock object above uses the Setup method to return the same result for the call defined in the r => r.FindById(1) lambda. This is called an expecation. This allows you to test only the code in your method, without actually calling out to any dependent classes.
Once you've set up your test this way, you can use Moq's features to confirm that everything happened the way it was supposed to:
//did we get the instance we expected?
Assert.AreEqual(thingie.Id, MyTestObject.GetThingies().First().Id);
//was a method called?
repMock.Verify(r => r.FindById(1));
The Verify method allows you to test whether a method was called. Together, these facilities allow you focus your unit tests on a single method at a time.
Sounds like your units are too tightly coupled (at least from a quick view at your problem). What makes me curious is for instance the fact that your UserGroups takes a UserDemographics and your UserSetupEvent takes a list of UserGroup including a list of UserDemographics (again). Shouldn't the List<UserGroup> already include the ÙserDemographics passed in it's constructor or am I misunderstanding it?
Somehow it seems like a design problem of your class model which in turn makes it difficult to unit test. Difficult setup procedures are a code smell indicating high coupling :)
Bringing in interfaces is what I would prefer. Then you can mock the used classes and you don't have to duplicate code (which violates the Don't Repeat Yourself principle) and you don't have to use the original implementations in the unit tests for the Communications class.
You should use mock objects, basically your unit test should probably just generate some fake data that looks like real data instead of calling into the real code, this way you can isolate the test and have predictable test results.
You can make use of a tool called NBuilder to generate test data. It has a very good fluent interface and is very easy to use. If your tests need to build lists this works even better. You can read more about it here.

Categories

Resources