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!)
Related
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.
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.
I don't have a lot of experience with unit testing. For example I have simple method in the application:
public void GetName()
{
UserRights rights = new UserRights(new DatabaseContext());
string test = rights.LookupNameByID("12345");
Console.WriteLine(test);
}
In this case I'm able to test all methods of UserRights class by passing mocked DatabaseContext, but how can I test GetName() method? What is the best practice? Where DatabaseContext should be created?
If you want to test the GetName method in a properly isolated way (i.e. a Unit Test) then you can't use new to create the UserRights instance in the method itself; because a test is really just another client of the code, therefore it can't (and shouldn't) know anything about how GetName works internally
So what this means is that for a proper Unit Test you must be able to replace all dependencies of a method with ones that the client fully controls - in the case, the code in the Unit Test is the client.
In your posted code, the client code has no control at all over UserRights nor DatabaseContext, so this is the first thing that has to change.
You need to rework your code so that the UserRights implementation can be supplied by the client. In fact once that's done, the problem about where DatabaseContext comes from is actually irrelevant for the Unit test because it doesn't care about how UserRights itself performs its tasks!
There are a number of ways of doing this; you can use Mocks or Stubs, you can use Constructor or Method injection, you could use a UserRights factory. Here is an example of using very simple stubs which IMHO is the best way to start and avoids having to learn a Mocking framework -- I personally would use Mocks for this but that's cos I am lazy :)
(code below assumes the class containing GetName is called "UserService", and uses xUnit framework; but MSTest will work just fine too)
Let's suppose you have control over the code of UserService so you can make the LookupNameByID method virtual (if you can't, then you may have to go the route if interfaces and mocks)
public class UserRights
{
public virtual LookupNameByID(string id)
{
//does whatever a UserRights does.
}
}
public class UserService
{
readonly UserRights _rights;
public UserService(UserRights rights)
{
_rights=rights; //null guard omitted for brevity
}
public string GetName(string id)
{
return _rights.LookupNameByID(id);
}
}
now in your unit test code suppose you create a sub-class of UserRights like this:
public class ExplodingUserRights: UserRights
{
public override string LookupNameByID(string id)
{
throw new Exception("BOOM!");
}
}
Now you can write a test to see how GetName reacts when something bad happens:
[Fact]
public void LookupNameByID_WhenUserRightsThrowsException_DoesNotReThrow()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new ExplodingUserRights()); <-Look, no DatabaseContext!
sut.GetName("12345");
}
and one for when good things happen:
public class HappyUserRights: UserRights
{
public override string LookupNameByID(string id)
{
return "yay!";
}
}
[Fact]
public void LookupNameByID_ReturnsResultOfUserRightsCall()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new HappyUserRights());
var actual = sut.GetName("12345");
Assert.Equal("yay!",actual);
}
and so on. Note that we never went anywhere near DatabaseContext, because that's a problem you only have to solve when you unit test the UserRights class itself. (and at that point I would probably recommend using Jeroen's advice from his linked article,and do an integration test, unless setup of a database for each test is something you can't or won't do, in which case you need to use interfaces and mocks)
Hope that helps.
Separating your codes reliance on DB Context is something you will want to investigate, this can be accomplished using the Repository pattern. Since you're passing the DB Context into your objects constructor, in this case UserRights, you can pretty easily change your code to take in an Interface (or simply add an overloaded contructor to the class that accepts an interface, then call that in your unit tests, preserving any existing code). There are lots of ways to get this done, a quick Google search yielded the following article:
http://romiller.com/2012/02/14/testing-with-a-fake-dbcontext/
http://www.codeproject.com/Articles/207820/The-Repository-Pattern-with-EF-code-first-Dependen
Once your class can accept an interface rather than (or as an alternative to) the strongly typed DB Context object you can use a Mock framework to assist with testing. Take a look at Moq for examples on how to use these in your unit tests https://github.com/Moq/moq4/wiki/Quickstart
Be Aware: Moq can become difficult to work with when your tests require data that is related via foreign keys, the syntax can be complicated to get your head around. One thing to watch out for is the temptation to make changes to your code just to make a unit test easier to set up, while there may be value in making this change it also may indicate that you need to re-think your unit test rather than violate your applications architecture and/or design patterns
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.
Lets say I have the below method called DoSomething.
When writing unit tests how do I know whether to use a Fake, Mock or Override approach and why is one better than the other?
public List<MyClass> DoSomething()
{
List<MyClass> data = GetData();
if (data.Count == 0)
return new List<MyClass>();
data = GetFormattedData(data);
if (data.Count == 0)
return new List<MyClass>();
return data;
}
[Test]
public void DoSomething_NoData_ReturnsEmptyList()
{
//Change method parameters to pass in IDataProvider that exposes GetData method
//Create FakeProvider class implementing IDataProvider
//Ensure FakeProvider.GetData returns no data
//Create FakeClass that inherits class from DoSomething class
//Make FakeClass.GetData return no data
//When DoSomething is called in the test it will call the parent class
//Create Mock of class that DoSomething/GetData/GetFormattedData is in
//Tell mock to make sure GetData returns empty list
//Call DoSomething in test
}
[Test]
public void DoSomething_NoFormattedData_ReturnsEmptyList()
{
//Same possibilities exist as above
}
In this case you could supply your function with the data so that the function signature would be public List<MyClass> DoSomething(List<MyClass data) Then your function would only have a single responsibility and that would be to format the data.
If you still want to do the data fetch withing your function and you will be accessing a database or external service I would use dependency injection and mocking to test the function.
Generally it is good to avoid dependencies if possible. It all depends of course, if you don't do any other data fetching in your class then it's just a matter of how far down you will send your dependency.
How exactly is fake approach different from override one? In both cases you'll most likely end up having to create new class inheriting from the one you want to test.
Anyways, I don't see much differences to be honest, and IMO you got two options:
mocking (which will require bit redesigning and dependency injection)
overriding (known as extract and override)
Both are valid and none is way better than the other. Problem with extract and override is that you'll need extra types/files. That of course means more stuff to manage by hand - if that can be avoided, it should be. Personally, I'd go with this one only when existing mocking frameworks can't handle your scenario.
Major advantage of mocking/injection technique is that it forces you to do better design - having SOLID principles in mind and overral writing more testable/managable code. Not to mention, there're many frameworks supporting this technique (Moq, RhinoMocks, FakeItEasy - to name the most popular ones).