I have the following code:
public class DB
{
public virtual int GetNumbers()
{
return 42;
}
}
public interface ITestable
{
int TestMethod();
}
public class Testable : ITestable
{
public int TestMethod()
{
DB db = new DB();
return db.GetNumbers() + 20;
}
}
Now I want to use MOQ to create a mock of DB, so that every time the DB is created and initialized (Just like in the Testable.TestMethod), it will use the mocked DB instance.
For example, maybe I can setup the DB Mock so that for all DB's instance, when the GetNumbers method is called, it will return 12 instead of 42. Such that the Testable.TestMethod will return 32, instead of 62.
I want to know is it possible for MOQ to handle such kind of scenario? Actually I know that TypeMock Isolator and Microsoft Fakes Framework can achieve this. And I also don't like to go with the "Test Driven Development" approach (Which means I need to adjust my design).
No, you cannot mock that with Moq nor any other dynamic proxy based framework. You don't need TDD (which has little to do with your problem) - what you should be looking at instead is Dependency Injection (this will alter your design).
Testable version of your code would require factory and abstraction over DB object, for example:
public class Testable : ITestable
{
private readonly Func<IDb> dbFactory;
public class Testable(Func<IDb> dbFactory)
{
this.dbFactory = dbFactory;
}
public int TestMethod()
{
var db = dbFactory();
return db.GetNumbers() + 20;
}
}
With Moq, this is the most common approach to such problems. You'll have to resort to paid tools if you want to stick with your current design.
Related
What is wrong with having the dependency object as a static field in a static class instead of injecting it to each object that depends on it through constructor?
public static class Dependencies
{
public static IUsersRepository Users;
...
}
//Use in a method that depends on Users Repository
var users = Dependencies.Users.GetUsers();
VS.
public class UserController
{
private IUsersRepository _users;
public UserController(IUsersRepository repo)
{
this._users = repo;
}
public List<User> GetCustomUsers()
{
var users = this._users.GetUsers();
...
}
}
There is a DI pattern called "Ambient Context" you can use to do this.
It allows you to avoid passing a cross-cutting concern all the time, but it still allows you to Unit Test things.
The canonical example is a DateTime provider:
public abstract class TimeProvider {
private static TimeProvider current =
DefaultTimeProvider.Instance;
public static TimeProvider Current {
get { return TimeProvider.current; }
set {
if (value == null) {
throw new ArgumentNullException("value");
}
TimeProvider.current = value;
}
}
public abstract DateTime UtcNow { get; }
public static void ResetToDefault() {
TimeProvider.current = DefaultTimeProvider.Instance;
}
}
Where an implementation might look like this:
public class DefaultTimeProvider : TimeProvider {
private readonly static DefaultTimeProvider instance =
new DefaultTimeProvider();
private DefaultTimeProvider() { }
public override DateTime UtcNow {
get { return DateTime.UtcNow; }
}
public static DefaultTimeProvider Instance {
get { return DefaultTimeProvider.instance; }
}
}
Code would use TimeProvider.Current to access the DateTime rather than using DateTime directly.
The default concrete implementation returns the usual DateTime.UtcNow. However, for unit testing you can use a special test implementation and set TimeProvider.Current to it before running the unit tests.
See this page (where that code comes from) for more information.
Note that you should only use this pattern for truly cross-cutting concerns such as DateTime, security, logging and so on.
Suppose that a UserController would like to use an instant IUsersRepository and another UserController would like to use an instance of a different IUserRepository implementation, then you can't do this with static dependencies.
To be honest, the police aren't going to come knocking on your door if you do, but taken to it's logical conclusion (i.e. an application of any appreciable size) you end up with a more difficult to maintain "spaghetti code" codebase.
Mostly, coupling, and things like the SOLID principles. You are tightly coupling to the Dependency class, when ideally DI prevents this by building object graphs for you, injecting the dependencies, so those objects have no knowledge (i.e. are not coupled) to the implementation that provides them. If you're using a DI container and a singleton lifestyle, then you've essentially got what you describe - static fields. But with a container (even the "containerless" style containers that are becoming popular) you get more flexibility and the hard things are done for you.
There are a few cases where using DI, particularly via a container, are probably a bad idea (logging, generating new Guid values, getting the current date). You can solve those few cases with the "ambient context" solution (see Matthew Watson's answer for more details).
I am using some COM library in my C# which is bound to particular hardware and doesn't work without it. On development/testing computer I don't have that hardware. The method which is using library looks like this:
using HWSysManagerLib;
bool ProcessBias(HWSysManager systemManager, string hwPath)
{
int handle = systemManager.OpenConfiguration(hwPath);
...
// some magic goes here
// return result
}
The question is, can I mock HWSysManager for test method and how? There are few methods only in HWSysManager and it wouldn't be problem to simulate their functionality for test. A tiny example would be great on how to mock it, if it's possible at all.
You can use the adapter pattern here.
Create an interface named IHWSysManager
public interface IHWSysManager
{
int OpenConfiguration(string hwPath);
}
The real implementation class just delegates the work to the library:
public class HWSysManagerImpl : IHWSysManager
{
private HWSysManager _hwSysManager; //Initialize from constructor
public int OpenConfiguration(string hwPath)
{
return _hwSysManager.openConfiguration(hwPath);
}
}
Use the interface in your code like this:
bool ProcessBias(IHWSysManager systemManager, string hwPath)
{
int handle = systemManager.OpenConfiguration(hwPath);
...
// some magic goes here
// return result
}
Now you can mock your IHWSysManager interface with mock frameworks or you can create a stub class yourself.
You can use Typemock Isolator for faking HWSysManager.
For your example, you can do the following:
var fakeManager = Isolate.Fake.Instance<HWSysManager>();
Isolate.WhenCalled(() => fakeManager.OpenConfiguration("")).WillReturn(0);
And then, you can pass this faked manager to ProcessBias(IHWSysManager systemManager, string hwPath) as an argument.
As you said, you can simulate a few methods from IHWSysManager. So, me advice is to set up the behavior of this manager's methods using DoInstead():
Isolate.WhenCalled(() => fakeManager.OpenConfiguration("")).DoInstead(
context =>
{
//Your simulation
});
You can look here for more information. I think, it can be really useful for you.
I suppose you should create HWSysManager(or some other name) class to your Mock cases, add there some wanted methods and then mock them. For example:
class HWSysManager
{
public virtual int ExampleReturnIntMethod(int a)
{
var someInt = 0;
return someInt;
}
and then setup:
public void TestMethod()
{
Mock<HWSysManager> hwSysManager = new Mock<HWSysManager>();
hwSysManager.Setup(x => x.ExampleReturnInMethod(It.IsAny<int> ())).Returns(10); //if parameter is any of int, return 10 in this case
}
Then to use your Mocked object just use the 'object' property:
var hwSysInstance = hwSysManager.Object;
var result = hwSysInstance.ExampleReturnInMethod(2); //result will be 10 in this case - as we have mocked
In case above your methods/properties have to be virtual.
You can use interfaces also, in your case:
public interface HwsysManager
{
int OpenConfiguration(string hwPath);
}
public void TestMethod()
{
Mock<HwsysManager> hwsysManager = new Mock<HwsysManager>();
hwsysManager.Setup(x => x.OpenConfiguration(It.IsAny<string>())).Returns(10);
}
All features of this Mock library are described here:
https://github.com/Moq/moq4/wiki/Quickstart
I have my POCO library and i have entities that implement an interface called IEntityDelete.
Interface is very simple, looks something like this
public interface IEntityDelete
{
bool IsDeleted { get; set; }
}
So i have an entity that implements this interface, again very simple, looks something like this
public class MyEntity() : IEntityDelete
{
public bool IsDeleted { get; set; }
}
I have an extension method, which i created this like
public static void MarkAsDeleted(this IEntityDelete entity)
{
entity.IsDeleted = true;
}
Then i needed to check if this method was being called within one of my service methods in my unit tests. Service method is very basic, looks something like this.
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
entity.MarkAsDeleted();
return _context.SaveChangesAsync();
}
Apparently you cannot test extension methods easily, without using Microsofts Moles framework, but i do not want another dependency.
I did some googl'ing and found 2 articles on this, and how to do about it, and would like to know if this is correct, or whether i have done something stupid.
Two articles i found where
http://adventuresdotnet.blogspot.co.uk/2011/03/mocking-static-methods-for-unit-testing.html
http://blogs.clariusconsulting.net/kzu/how-to-mock-extension-methods/
They recommend using a wrapper class which aint static, so i ended up with this.
First created my wrapper interface
public interface IEntityDeleteWrapper
{
void MarkAsDeleted(IEntityDelete entity);
}
Create a class that implements this interface
public class EntityDeleteWrapper : IEntityDeleteWrapper
{
public void MarkAsDeleted(IEntityDelete entity)
{
entity.IsDeleted = true;
entity.DeletedDate = DateTime.Now;
entity.DeletedByUserId = 546372819;
}
}
Inject this interface into my service constructor
public MyService(IEntityDeleteWrapper deleteWrapper)
{
_deleteWrapper = deleteWrapper;
}
Change my service method call to use the wrapper like so
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
_deleteWrapper.MarkAsDeleted(entity);
return _context.SaveChangesAsync();
}
SOLVED
As i was told, this was way too far to go, i can just check if a property has changed. In light of this, i am using my extension method still and updated my unit test to this.
[TestMethod]
public void should_mark_entity_as_deleted()
{
// arrange
var entity = new Attachment
{
IsDeleted = false
};
// act
var result = _service.DeleteByFlagAsync(entity).Result;
// assert
Assert.AreEqual(true, entity.IsDeleted);
_context.Verify(e => e.SaveChangesAsync(), Times.Once);
}
You went too far. Your test should verify observable change to state, not how that change was made. Otherwise you make your tests very brittle, not to mention you add rather unnecessary extra layer. It would be enough to check whether entity properties changed after DeleteByFlagAsync call.
Of course, when deleting gets more complex introducing dependency to delegate this task to makes sense. But then, few questions arise:
What would be the scope of DeleteByFlagAsync? Call two dependencies?
Would it be practical to test it?
...or perhaps tests for said dependency would suffice (as this is where the actual mark-for-deletion will take place)?
I have the following code:
public interface IProductDataAccess
{
bool CreateProduct(Product newProduct);
}
Class ProductDataAccess implements that interface.
public class ProductBusiness
{
public bool CreateProduct(Product newProduct)
{
IProductDataAccess pda = new ProductDataAccess();
bool result = pda.CreateProduct(newProduct);
return result;
}
}
In this case, how to create unit test for CreateProduct method by mocking the IProductDataAccess interface? I thought of having an public instance of IProductDataAccess within ProductBusiness and initialize it using Mock<IProductDataAccess> object but it is not a good practice to expose the data access to the UI layer. Can any one help me?
Classic example which demonstrates that if you cannot unit test a particular component, REFACTOR it!
This is why I love what any mocking framework enforces you to do - write decoupled code.
In your example, the ProductBusiness class is tightly coupled with the ProductDataAccess class. You could decouple it using (like most of the answers suggest) dependency injection. By doing so, you would end up depending on the IProductDataAccess abstraction and not on any concrete implementation of it.
Another point to note, when you are writing tests/specifications for the business layer, you would typically want to test the "behavior" and not the "state". So, although you could have asserts that verify if "true" was returned, your tests should really test if the expected data access calls that were set using MOQ were actually executed using the .Verify API of MOQ.
Try adding behavior tests where you expect an exception to be thrown (using the ".Throws" API) by the data access layer and check if you need any special handling at the business layer.
Like Kevin suggests, the following implementation of ProductBusiness will work:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result=_productDataAccess.CreateProduct(newProduct);
return result;
}
}
and use any xunit testing framework to write the test as:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess.Setup(m => m.CreateProduct(It.IsAny<Product>())).Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
//behavior to be tested
You should inject IProductDataAccess interface as a dependency:
public class ProductBusiness
{
private IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result = _productDataAccess.CreateProduct(newProduct);
return result;
}
}
Then you can replace it with a mock in your tests:
var productDataAccess = new Mock<IProductDataAccess>();
var productBusiness = new ProductBusiness(productDataAccess.Object);
With the way that you have currently designed your ProductBusiness class there is no way of changing the IProductDataAccess implementation using a mock. A recommended pattern for this is dependency-injection where you take the dependencies of a type through the constructor. So your class becomes:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result = _productDataAccess.CreateProduct(newProduct);
return result;
}
}
Now you are in a position to test your class by using a mocking framework like moq. For example:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess
.Setup(m => m.CreateProduct(It.IsAny<Product>()))
.Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
// ... test behaviour here
Now you can change how the mock behaves in your setup step and make sure that your CreateProduct method is behaving correctly.
I would also look at a dependency injection framework like castle-windsor. A dependency injection framework can automatically resolve dependencies meaning creating a new type is much easier as you don't have to manually new everything up. Also it means that you can change which implementation is used in one place and it changes everywhere.
You shouldn't instantiate a concrete ProductDataAccess inside your CreateProduct method.
Instead, IProductDataAccess should be an injectable dependency. This can be done in one of two ways:
Property injection:
public class ProductBusiness
{
IProductDataAccess Pda {get; set;}
}
var productBusiness = new ProductBusiness();
productBusiness.Pda = new ProductDataAccess();
productBusiness.Pda = new MockProductDataAccess();
Or constructor injection:
public class ProductBusiness
{
private readonly IProductDataAccess _pda;
public ProductBusiness(IProductDataAccess pda)
{
_pda = pda;
}
}
var productBusiness = new ProductBusiness(new ProductDataAccess());
var productBusiness = new ProductBusiness(new MockProductDataAccess());
Constructor injection is usually the recommend approach.
Property injection is used for optional dependencies (e.g., instantiate a concrete NullLogger by default in the constructor, and use the property to optionally inject a working logger).
I have been making a little toy web application in C# along the lines of Rob Connery's Asp.net MVC storefront.
I find that I have a repository interface, call it IFooRepository, with methods, say
IQueryable<Foo> GetFoo();
void PersistFoo(Foo foo);
And I have three implementations of this: ISqlFooRepository, IFileFooRepostory, and IMockFooRepository.
I also have some test cases. What I would like to do, and haven't worked out how to do yet, is to run the same test cases against each of these three implementations, and have a green tick for each test pass on each interface type.
e.g.
[TestMethod]
Public void GetFoo_NotNull_Test()
{
IFooRepository repository = GetRepository();
var results = repository. GetFoo();
Assert.IsNotNull(results);
}
I want this test method to be run three times, with some variation in the environment that allows it to get three different kinds of repository. At present I have three cut-and-pasted test classes that differ only in the implementation of the private helper method IFooRepository GetRepository(); Obviously, this is smelly.
However, I cannot just remove duplication by consolidating the cut and pasted methods, since they need to be present, public and marked as test for the test to run.
I am using the Microsoft testing framework, and would prefer to stay with it if I can. But a suggestion of how to do this in, say, MBUnit would also be of some interest.
Create an abstract class that contains concrete versions of the tests and an abstract GetRepository method which returns IFooRepository.
Create three classes that derive from the abstract class, each of which implements GetRepository in a way that returns the appropriate IFooRepository implementation.
Add all three classes to your test suite, and you're ready to go.
To be able to selectively run the tests for some providers and not others, consider using the MbUnit '[FixtureCategory]' attribute to categorise your tests - suggested categories are 'quick' 'slow' 'db' 'important' and 'unimportant' (The last two are jokes - honest!)
In MbUnit, you might be able to use the RowTest attribute to specify parameters on your test.
[RowTest]
[Row(new ThisRepository())]
[Row(new ThatRepository())]
Public void GetFoo_NotNull_Test(IFooRepository repository)
{
var results = repository.GetFoo();
Assert.IsNotNull(results);
}
If you have your 3 copy and pasted test methods, you should be able to refactor (extract method) it to get rid of the duplication.
i.e. this is what I had in mind:
private IRepository GetRepository(RepositoryType repositoryType)
{
switch (repositoryType)
{
case RepositoryType.Sql:
// return a SQL repository
case RepositoryType.Mock:
// return a mock repository
// etc
}
}
private void TestGetFooNotNull(RepositoryType repositoryType)
{
IFooRepository repository = GetRepository(repositoryType);
var results = repository.GetFoo();
Assert.IsNotNull(results);
}
[TestMethod]
public void GetFoo_NotNull_Sql()
{
this.TestGetFooNotNull(RepositoryType.Sql);
}
[TestMethod]
public void GetFoo_NotNull_File()
{
this.TestGetFooNotNull(RepositoryType.File);
}
[TestMethod]
public void GetFoo_NotNull_Mock()
{
this.TestGetFooNotNull(RepositoryType.Mock);
}
[TestMethod]
public void GetFoo_NotNull_Test_ForFile()
{
GetFoo_NotNull(new FileRepository().GetRepository());
}
[TestMethod]
public void GetFoo_NotNull_Test_ForSql()
{
GetFoo_NotNull(new SqlRepository().GetRepository());
}
private void GetFoo_NotNull(IFooRepository repository)
{
var results = repository. GetFoo();
Assert.IsNotNull(results);
}
To Sum up, there are three ways to go:
1) Make the tests one liners that call down to common methods (answer by Rick, also Hallgrim)
2) Use MBUnit's RowTest feature to automate this (answer by Jon Limjap). I would also use an enum here, e.g.
[RowTest]
[Row(RepositoryType.Sql)]
[Row(RepositoryType.Mock)]
public void TestGetFooNotNull(RepositoryType repositoryType)
{
IFooRepository repository = GetRepository(repositoryType);
var results = repository.GetFoo();
Assert.IsNotNull(results);
}
3) Use a base class, answer by belugabob
I have made a sample based on this idea
public abstract class TestBase
{
protected int foo = 0;
[TestMethod]
public void TestUnderTen()
{
Assert.IsTrue(foo < 10);
}
[TestMethod]
public void TestOver2()
{
Assert.IsTrue(foo > 2);
}
}
[TestClass]
public class TestA: TestBase
{
public TestA()
{
foo = 4;
}
}
[TestClass]
public class TestB: TestBase
{
public TestB()
{
foo = 6;
}
}
This produces four passing tests in two test classes.
Upsides of 3 are:
1) Least extra code, least maintenance
2) Least typing to plug in a new repository if need be - it would be done in one place, unlike the others.
Downsides are:
1) Less flexibility to not run a test against a provider if need be
2) Harder to read.