I have read that you need to define interfaces in order to mock types but I am not sure how to interpret that.
For example, to mock FileSystem, instead of directly calling some I/O method, I can pass the object to the method and then mock it when calling from my test.
Why are unit test examples (like the one from SO question below), use interfaces?
void DoIt(IZipper zipper, IFileSystem fileSystem, IDllRunner runner)
{
string path = zipper.Unzip(theZipFile);
IFakeFile file = fileSystem.Open(path);
runner.Run(file);
}
Could I not simply use arguments of respective types, and inject the object then?
E.g. in the GUICE guide, they advise to remove constructor work (e.g. no field inicialization with "new" keyword), but use parameters istead.
It depends on your mocking framework. Using Moq, you can mock concrete types as long as they aren't sealed and the members you want to mock are virtual. Interfaces are generally preferred because their members don't need to (and can't) be marked as virtual. (There are other reasons to prefer interfaces such as to keep the coupling between your classes loose)
https://github.com/Moq/moq4/wiki/Quickstart
Update
Generally you will mock an instance of a type. Therefore you can't test static method calls like FileStream.Open because there is no instance to mock.
Update
Frameworks like Moq rely on inheritance to generate the mocks. That's why methods need to be virtual. If you want to mock static or private methods, try Microsoft Fakes.
https://msdn.microsoft.com/en-us/library/hh549175.aspx
It is not must to have interface as dependency but that's recommended and widely followed practice.
Using interface and base classes as dependency helps you creating lossely couple design.
Loosely coupled design makes it possible to create modules/layers of application without depending on the implementation details about other layer.
This also makes it super easy to test the piece of code in isolation without worrying about how other layer would work or react.
This type of testing is called unit testing.
If you have dependency on concrete class then you can't unit test code in isolation. Such tests are prone to fail whenever implementation of dependency changes. If your code is dependent on actual file system class or data access class which connects to actual db then there are chances that the unit tests will fail when file is not accessible or db server is down or data is currupted.
This even won't be called unit testing. It is called integration testing.
As I mentioned, while testing code in isolation you don't need to worry about how the dependency works. That's why, while unit testing the dependencies are mocked. Also dependencies must not be an interface. It can be a base class too. When you mock dependency, mocks do not have actual implementation of any of the functionality. How many ways you can create mocks, is a different topics altogether.
Using mocks, in unit testing, you just need to make sure that they behave per your expectations while you test the code your current class. So you ask the mock to behave the way you want, make sure that certain methods or properties of mock called, so that you can cover all the paths of the piece of code which you are testing.
Following is a simple example of Unit Testing with dependency.
public class ProductService
{
private IProductRepository repository;
public ProductService (IProductRepository repository)
{
this.repository = repository;
}
public Product GetProductById(int productId)
{
if(productId <= 0)
return null;
var product = this.repository.GetProductById(productId);
return product;
}
}
While Creating ProductService class, even if I don't have actual implementation of IProductRepository interface, I can still unit test ProductService class as following.
public class ProductServiceTests
{
ProductService serviceToTest;
IProductRepository productRepository;
public ProductServiceTests()
{
this.productRepository = Mock<IProductRepository>();
this.serviceToTest = new ProductService(productRepository);
}
public void GetProductByIdReturnsNullIfProductIdIsZero()
{
int productid = 0;
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Null);
}
public void GetProductByIdReturnsNullIfProductIdIsNegative()
{
int productid = -1;
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Null);
}
public void GetProductByIdReturnsProductIfProductIdIsPositive()
{
var productid = 1;
var product = new Product { Id = productId };
productRepository.Setup(repo => repo.GetProductById(productid)).Returns(product); //Making sure that GetProductById method of repository is called and return an object of product as this call is part of the code which I am testing right now.
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Not.Null);
Assert.That(product.Id, Is.EqualTo<int>(productid));
}
}
This is an example code to illustrate the unit testing. It might not build or run as expected and I apologies for that.
edit
Found an excellent article on mocking classes https://www.wrightfully.com/how-net-mocking-frameworks-work
This should clear doubts of how class mocking is different than the interface mocking.
Related
I use a dependency injection framework AutoFac in NUnit as described
here
The classes are registered as SingleInstance scope.
one of the classes depends on Setting class, as given below:
class Product
{
public (Setting setting, Dep1 dependency) {.... }
....
}
I want to update the properties of one of the classes "Setting" per test case.
[Test]
public void Test()
{
//Arrange
var setting = Resolve<Setting>
Setting.Id = value
// product depend on two dependency injected via constructor
var product = Resolve<Product> ;
//the problem is: the new values of setting class are not reflected in
//Product, and the Product still use the default values provided by the container
......
}
The problem is the updated value is not reflected in the container and unit test fail and the Product class still use the default values
I tried to use this solution, but it can't help.The Documentation of AutoFac don't provide guidelines of using in NUnit or test suite.
The question: How can I update the values of the class setting and the new values are auto injected in the constructor of product class in NUnit?
The Short Answer
You don't.
The Long Answer
Each application should have its own Composition Root. Since a test project is a separate application from the class under test, you would never share a production configuration with a test configuration.
When unit testing, you typically don't deal with more than half a dozen or so dependencies at a time. It would be impractical to setup a DI container for this purpose. Instead, you should new up the class under test and mock everything else except for DTO and Model objects.
[Test]
public void Test()
{
var setting = new Setting { Value1 = "x", Value2 = "y" };
var dep1 = new Mock<Dep1>();
// setup Moq conditions on dep1
var product = new Product(setting, dep1);
// Execute method on product and assert
}
When integration testing, it is also better to use pure DI than to setup a DI container just for the purpose of testing. However, if you do use a DI container, it should have its own configuration separate from the application that is being tested. Even if this weren't considered a bad practice, there will be dependencies that need to be mocked that warrant this anyway. You are not testing the DI container configuration, you are testing the components of your application, so there is no need to make them one and the same.
NOTE: It is strongly advised to use abstractions rather than concrete types as constructor parameters. The usual route is to use interfaces (although I would argue that "settings" might not need to be), but abstract classes will also work.
Instead of trying to update the properties of your Settings class, you can create an interface to represent your settings, like
public interface ISettings
{
int Value { get; }
}
Inject that interface, not a concrete class, into your Product class. Your concrete implementation might read from a configuration file, or you could have an implementation with hard-coded values - whatever you need.
But now that your class depends on that interface, for testing you have a number of options for mocking it.
You could use a test double, like:
public class SettingsDouble : ISettings
{
public int Value { get; set; }
}
Or you could use Moq.
var settingsMock = new Mock<ISettings>();
settingsMock.Setup(x => x.Value).Returns(1);
A side effect is that your ISettings interface and implementations can have read-only properties. Chances are that you don't want classes setting those properties at runtime and affecting other classes' settings, but you made it writable for the purpose of unit testing. Now you don't have to do that.
I am attempting to mock (using Moq) a classes and interfaces that are defined in a third party SDK. Here's a simplified example of what they look like:
public interface IVehicle
{
string Type { get; }
}
public class Vehicle
{
public string Type { get; }
}
public class Jeep : Vehicle, IVehicle
{
}
I can easily mock the interface like so:
var mockVehicle = new Mock<IVehicule>(MockBehavior.Strict);
mockVehicle
.SetupGet(v => v.Type)
.Returns("My custom vehicle");
but I need to write a unit test specific to the Jeep class and I can't figure out how to mock it.
My first attempt:
var mockJeep = new Mock<Jeep>(MockBehavior.Strict);
yielded the following error:
Moq.MockException: IVehicle.Type invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
which is understandable since I haven't setup the Type property.
My second attempt:
var mockJeep = new Mock<Jeep>(MockBehavior.Strict);
mockJeep
.SetupGet(v => v.Type)
.Returns("Jeep");
yielded the following error message:
System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: v => v.Type
which is also understandable since the Type property on the Vehicle class is not virtual.
So my question is: is there a way to setup the Type property when mocking the Jeep class?
The best Moq can do in this case is create a proxy as a derived class of Jeep but it cannot override the non-virtual Type property. Remember that when you attempt to create a Mock with Moq, the framework generates a class that either implements the target interface or derives from the target class.
Microsoft Fakes work well with Moq provided that you have the Visual Studio license level to access it.
Since this is a rather generalized question, I'm going to suggest a different approach. Mocking / Faking / Stubbing a class or interface that you don't control is generally difficult. Furthermore, this typically leads to replicating someone else's functionality in your mock instance.
A better approach is to isolate interaction with the external library into a wrapping class that you control the interface and implementation of. This will allow you to easily mock/fake/stub your interface for testing consumers of your interface.
This still leaves the question of what to do with the isolation layer class. For this, you'll need to do more of an integration test that actually exercises both your wrapping class and the external class. Then, verify that you get the expected behavior from the combination of your class and the external classes you're wrapping.
So my question is: is there a way to setup the Type property when mocking the Jeep class?
The short answer is no, you cannot Mock a non virtual member using Moq.
However, I don't think there's any reason in this case to mock anything, since there isn't any behaviour to mock. The only member you have there is a simple string property. So even if you could, you probably shouldn't.
If you are trying to test the Jeep class, just test it directly
without mocking any of its members; mocking should only be used when you need to control the behaviour of one of the dependencies of the System Under Test (SUT)
If you are passing the Jeep
class to another method as a dependency in order to test that method, you can just
new up a Jeep instance and pass it in your test in this case; since it doesn't
have any boundary-crossing behaviours (network calls, etc) then there
is no need to mock it.
You might also consider that if it's the second case, you ought to be able to pass an IVehicle instead of a Jeep, in which case mocking is back on the table (although as mentioned, there is no apparent need in this case)
Incidentally, your hierarchy looks a little off - why does Vehicle not itself implement IVehicle?
i.e.
public interface IVehicle
{
string Type { get; }
}
public class Vehicle: IVehicle
{
public string Type { get; }
}
public class Jeep : Vehicle
{
}
Then Jeep will already be both a Vehicle and an IVehicle :)
disclaimer: I work at Typemock.
By using Typemock Isolator you will be able to mock non-virtual methods and won't need to change your code in order to do so, in this specific example you can fake an instance of Jeep and then modify his methods behavior.
Here is an example for a test that mock Jeep:
[TestMethod]
public void CallFakeJeepType_WillReturnWantedString()
{
var jeep = Isolate.Fake.Instance<Jeep>();
Isolate.WhenCalled(() => jeep.Type).WillReturn("fake jeep");
var result = Jeep.DoSomthing(jeep);
Assert.AreEqual("fake jeep", result);
}
note: if the Jeep.Type had a setter as well you could use typemock's True property and the test will look like this
var jeep = Isolate.Fake.Instance<Jeep>();
jeep.Type = "fake jeep";
I've been reading up on how to write testable code and stumbled upon the Dependency Injection design pattern.
This design pattern is really easy to understand and there is really nothing to it, the object asks for the values rather then creating them itself.
However, now that I'm thinking about how this could be used the application im currenty working on I realize that there are some complications to it. Imagine the following example:
public class A{
public string getValue(){
return "abc";
}
}
public class B{
private A a;
public B(A a){
this.a=a;
}
public void someMethod(){
String str = a.getValue();
}
}
Unit testing someMethod () would now be easy since i can create a mock of A and have getValue() return whatever I want.
The class B's dependency on A is injected through the constructor, but this means that A has to be instantiated outside the class B so this dependency have moved to another class instead. This would be repeated many layers down and on some point instantiation has to be done.
Now to the question, is it true that when using Dependency Injection, you keep passing the dependencys through all these layers? Wouldn't that make the code less readable and more time consuming to debug? And when you reach the "top" layer, how would you unit test that class?
I hope I understand your question correctly.
Injecting Dependencies
No we don't pass the dependencies through all the layers. We only pass them to layers that directly talk to them. For example:
public class PaymentHandler {
private customerRepository;
public PaymentHandler(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
public void handlePayment(CustomerId customerId, Money amount) {
Customer customer = customerRepository.findById(customerId);
customer.charge(amount);
}
}
public interface CustomerRepository {
public Customer findById(CustomerId customerId);
}
public class DefaultCustomerRepository implements CustomerRepository {
private Database database;
public CustomerRepository(Database database) {
this.database = database;
}
public Customer findById(CustomerId customerId) {
Result result = database.executeQuery(...);
// do some logic here
return customer;
}
}
public interface Database {
public Result executeQuery(Query query);
}
PaymentHandler does not know about the Database, it only talks to CustomerRepository. The injection of Database stops at the repository layer.
Readability of the code
When doing manual injection without framework or libraries to help, we might end up with Factory classes that contain many boilerplate code like return new D(new C(new B(), new A()); which at some point can be less readable. To solve this problem we tend to use DI frameworks like Guice to avoid writing so many factories.
However, for classes that actually do work / business logic, they should be more readable and understandable as they only talk to their direct collaborators and do the work they need to do.
Unit Testing
I assume that by "Top" layer you mean the PaymentHandler class. In this example, we can create a stub CustomerRepository class and have it return a Customer object that we can check against, then pass the stub to the PaymentHandler to check whether the correct amount is charged.
The general idea is to pass in fake collaborators to control their output so that we can safely assert the behavior of the class under test (in this example the PaymentHandler class).
Why interfaces
As mentioned in the comments above, it is more preferable to depend on interfaces instead of concrete classes, they provide better testability(easy to mock/stub) and easier debugging.
Hope this helps.
Well yes, that would mean you have to pass the dependencies over all the layers. However, that's where Inversion of Control containers come in handy. They allow you to register all components (classes) in the system. Then you can ask the IoC container for an instance of class B (in your example), which would automatically call the correct constructor for you automatically creating any objects the constructor depends upon (in your case class A).
A nice discussion can be found here: Why do I need an IoC container as opposed to straightforward DI code?
IMO, your question demonstrates that you understand the pattern.
Used correctly, you would have a Composition Root where all dependencies are resolved and injected. Use of an IoC container here would resolve dependencies and pass them down through the layers for you.
This is in direct opposition to the Service Location pattern, which is considered by many as an anti-pattern.
Use of a Composition Root shouldn't make your code less readable/understandable as well-designed classes with clear and relevant dependencies should be reasonably self-documenting. I'm not sure about unit testing a Composition Root. It has a discreet role so it should be testable.
Often times, a class would not have a direct output; it manipulates its dependencies, making them do things.
For example:
internal interface IEmailer
{
void SendEmail();
}
class ReportSender
{
public IEmailer Emailer { get; set; }
public ReportSender(IEmailer emailerToUse)
{
Emailer = emailerToUse;
}
public void SendReport()
{
// Do whatever is needed to create the report
Emailer.SendEmail();
}
}
Creating a mock of IEmailer and make it expect IEmailer.SendEmail() seem to be exposing too much of the innards of the class and making the test fragile.
But I can't think of any other way to test this class.
How should we write unit tests for such a class?
Making a mock of IEmailer doesn't by itself expose too much of the class. Rather, it makes it open for extensibilty.
There's a certain tendendency that heavily relying on interaction-based testing (i.e. mocks) makes tests more fragile, but this is more of a design issue than an issue with mocks.
The Hollywood Principle can be really helpful here, because if your dependencies are mostly designed around void methods, dynamic mocks like Moq or Rhino Mocks will generally just ignore the method calls unless you specifically tell them to care about a particular one.
Using Mock objects is the correct way to write the unit test for this method. You don't want your test to actually send an email. Mock objects let you break dependencies between different classes for the purposes of unit testing.
Here's an example using Rhino Mocks.
http://www.ayende.com/projects/rhino-mocks.aspx
IEmailer emailer = MockRepository.GenerateMock<IEmailer>();
emailer.Expect(x => x.SendEmail());
ReportSender reportSender = new ReportSender();
reportSender.Emailer = emailer;
reportSender.SendReport();
emailer.VerifyAllExpectations();
Creating a mock of IEmailer and make it expect IEmailer.SendEmail()
is exactly the way you would test that.
since these are UNIT tests, you are not exposing too much. you are supposed to be exercising all the functions of the unit to be tested, and it's alright if you have internal knowledge of the unit.
I'm not very experienced with unit testing yet, so this might not be too helpful... but it seems to me your suggestion of mocking out the dependency is on the right track. You can then probe the state of the mocked dependencies after the operation completes, to determine whether or not the IEmailer performed the expected manipulations on them?
Creating a mock IEmailer and expecting a call to SendEmail is the proper way to test this scenario.
Creating a mock of IEmailer and make it expect IEmailer.SendEmail() seem to be exposing too much of the innards of the class and making the test fragile.
Then why are you exposing a public property requiring an internal interface?
Make the interface public and your implementations of them internal.
Given a basic repository interface:
public interface IPersonRepository
{
void AddPerson(Person person);
List<Person> GetAllPeople();
}
With a basic implementation:
public class PersonRepository: IPersonRepository
{
public void AddPerson(Person person)
{
ObjectContext.AddObject(person);
}
public List<Person> GetAllPeople()
{
return ObjectSet.AsQueryable().ToList();
}
}
How can you unit test this in a meaningful way? Since it crosses the boundary and physically updates and reads from the database, thats not a unit test, its an integration test.
Or is it wrong to want to unit test this in the first place? Should I only have integration tests on the repository?
I've been googling the subject and blogs often say to make a stub that implements the IRepository:
public class PersonRepositoryTestStub: IPersonRepository
{
private List<Person> people = new List<Person>();
public void AddPerson(Person person)
{
people.Add(person);
}
public List<Person> GetAllPeople()
{
return people;
}
}
But that doesnt unit test PersonRepository, it tests the implementation of PersonRepositoryTestStub (not very helpful).
In this specific case I think you don't need to make a unit test for your repository class, as the implementation is simply invoking the ObjectContext object, so it will be like testing something you didn't build (which is not the idea). In case you don't have any complex logic, my recommendation is not to waste time on making a unit test for that class. What you say about the PersonRepositoryTestStub is a fake implementation of the repository for testing the layer that is above of your DAL.
I have run into the same problem. I wrote a slew of unit tests against an implementation of my repository interface that was a fake repository. Shortly after completing it, I realized that I wrote the unit test to test the fake repository and I wrote the fake repository simply to support the unit tests. This seemed like a large amount of useless code.
I have come to the conclusion that I don't need the unit tests but that the fake repository implementation is good because I can use it as the repository my services (and therefore my controllers) use so that unit tests against those will be predictable (thanks to a predefined fake repository).
So, I have decided to leave the unit tests against the fake repository in there as they are helpful to test my fake repository so that I can be assured that the higher levels of my application are using fully tested fakes.
In other words, the fake repository and the unit tests against the fake repository are the "supporting cast" for higher levels of the applications and the unit tests against higher levels of the application.
Hope that helps.
The time when I think this type of testing makes sense is when your repository interface is generic. E.g.
public interface IEntity
{
int Id { get; set; }
}
public interface IRepository<TEntity>
where TEntity : IEntity
{
void Add(TEntity entity);
List<TEntity> GetAll();
}
If you have multiple implementations of that interface, then it is also possible to write a generic test fixture that tests against that interface, allowing you to test multiple repository implementations with a single test fixture. This approach does not differentiate between unit and integration tests, because it has no idea what the implementation is.
Let me know if this type of thing interests you and I can post a complete example.
I would test Business Logic layer that depends on DAL implementation directly (has strong reference to DAL exact implementation) or indirectly (abstracted from DAL via interfaces).
I am not very fond of tests, that uses stub implementation, just wrap database calls into uncomitted transaction (that rolls back all data changes when test finishes even if exception is thrown).