I am coming from the .NET world (C#) to Java (Android development).
Many mocking frameworks and tools from the .NET space allow replacing/overriding class/method usage without injecting any mock objects into tested methods (Microsoft Fakes is one).
For example, in the following method:
public void SomeMethod()
{
new SomeOtherClass().Do("This is a test!");
}
Calling the SomeOtherClass().Do method can be made to return a specific value or to behave in a certain manner, even though i have not injected a mock object for this class into this method.
Using Microsoft Fakes for example, this can be done by code simliar to this:
using (ShimsContext.Create())
{
// decide what to do when Do() gets called
System.Fakes.ShimSomeOtherClass.Do = str => ....
new SomeOtherClass().Do("blabla");
}
As far as i've seen in the Java/Android mocking world, doing something like that is impossible. I would have to refactor all my code to inject its dependencies for every method.
While this may be a good practice indeed in some places, it would be impossible to do in all code locations.
Is there any way to achieve this with Java?
Frameworks i'm working with: Mockito, PowerMock, Robolectric
You can mock the instantiation of a new object with PowerMock using expectNew()
http://code.google.com/p/powermock/wiki/MockConstructor
SomeOtherClass someOtherMock = createMock(SomeOtherClass.class);
expectNew(SomeOtherClass.class).andReturn(someOtherMock);
expect(someOtherMock.do("blabla")).andReturn(...);
Edit: You can use with Mockito with the PowerMockito extensions
http://code.google.com/p/powermock/wiki/MockitoUsage
PowerMockito.whenNew(SomeOtherClass.class)...
I'm pretty sure Mockito does what you are asking, here's some of my test code:
SnapshotManager snapshotManager = mock(SnapshotManager.class);
when(snapshotManager.storeBroadcast("MessageURL1", "B1")).thenReturn(new Distribution("AltMessageURL1", 1));
The syntax is more complex, but the behaviour is the same.
The String literals in the storeBroadcast method do not need to be Strings they can be set to constrain values too.
Plus you have the option to spy on values and to verify the expected methods were called after you injected the instance into your code.
Related
I have to work with some legacy code that I cannot change. I have to write classes of that implement an interface called "ITask" that has a method called "RunTask" that accepts a concrete type called Schedule e.g;
public void RunTask(Schedule thisSchedule)
{
//I have to do stuff with thisSchedule, no I can't fix that name...
}
Although the legacy code does not use unit testing I would dearly like to use it for my work but the problem is "thisSchedule". I have made a fake version of Schedule that derives from it and am attempting to take control over how all the methods within it function (it is probably a fool's errand). So far I have been successful by exploiting the alarming number of virtual methods or by using reflection but I have hit my first show-stopper
I cannot connect to the real database and I have a method that is often called;
public void BeginTransaction()
{
MyTransaction = MyConnection.BeginTransaction(IsolationLevel.RepeatableRead);
}
internal SqlConnection MyConnection = new System.Data.SqlClient.SqlConnection();
This throws an exception because the connection is closed, Ideally I would like to be able to set a flag stating that the method was called and then just swallow the exception but I would be happy to simply ignore the exception.
Anything, no matter how nasty that will allow me to get past this method call would be an acceptable answer. It's that or defeat.
I am not allowed to use paid-for services like typeMock or shims in visual studio enterprise.
EDIT
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data;
using System.Data.SqlClient;
namespace PredictionServicesTests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void BeginTransaction_WhenCalled_SetsTransactionStartedToTrue()
{
Schedule schedule = new FakeSchedule();
schedule.BeginTransaction(); //It would be enough to simply get past this line to the Assert
Assert.IsTrue(((FakeSchedule)schedule).TransactionStarted); //This would be nice, but isn't vital
}
class Schedule
{
private SqlTransaction MyTransaction;
internal SqlConnection MyConnection = new System.Data.SqlClient.SqlConnection();
public void BeginTransaction()
{
MyTransaction = MyConnection.BeginTransaction(IsolationLevel.RepeatableRead);
}
}
class FakeSchedule : Schedule
{
public bool TransactionStarted { get; set; }
}
}
}
Please remember I cannot change the Schedule class, if only things could be that simple!
The ITask interface;
interface ITask
{
void RunTask(Schedule thisSchedule);
}
When it comes to unit testing, any external dependency needs to be isolated. Different frameworks have different ways of isolating external dependencies, as well as limitations of what they can isolate.
Many frameworks allow you to create a mock of an interface, so that you can provide an implementation for members in a controlled state. A lot of these frameworks also work well with abstract members of abstract classes. However, very few frameworks support the ability to provide an implementation on a concrete class (non-abstract member). The only two I'm aware which are available are:
Typemock Isolator
Microsoft Fakes
Both of these frameworks utilize the .NET Profiler API to intercept member calls to replace them with code you provide. I'm not too familiar with TypeMock Isolator, but I am very familiar with Microsoft Fakes. The Microsoft Fakes framework supports generating an assembly (i.e. System.Fakes.dll) which contains classes that allow you to provide your own implementation on members. It supports creating Stubs against interfaces and abstract classes (equivalent to "mocks"), and Shims against concrete and static classes.
If you choose to use Microsoft Fakes, you'll first need to generate a fake assembly against System.Data.dll, which is where SqlConnection resides. This will generate the ShimSqlConnection class, and this class will contain members which allow you to provide alternative implementations of the SqlConnection class' members. Here is an example of how that could be done:
[TestMethod]
public void SampleTest()
{
using (ShimsContext.Create())
{
// Arrange
SqlConnection.AllInstances.BeginTransactionIsolationLevel =
(instance, iso) => { ... };
// Act
// Assert
}
}
Of course, whether it is a mock, shim, stub, whatever... you should provide alternative implementation which simulates the behavior you want. Since you are replacing the SqlConnection.BeginTransaction(IsolationLevel) member, you must still follow it's contract and expected behavior; you should not return a value or throw an exception that the actual implementation would not do. At my company, we utilize Microsoft Fakes to simulate scenarios such as:
What happens if a Stream is closed when we read from it?
What happens if the user/pass is wrong for an HttpWebRequest?
What happens if we want our database to return two rows (i.e. control the SqlDataReader.Read() member)?
In all of these scenarios, our goal was to isolate the implemented behavior of these members and replace them with implementations which could realistically occur in a controlled experiment.
Update:
I just noticed that the original poster stated "I am not allowed to use paid-for services like typeMock or shims in visual studio enterprise.". If that is a restriction, then you will have to find another tool that I am unaware of that utilizes the .NET Profiler API or utilize the framework yourself. Profiling (Unmanaged API Reference).
The fact that you are "newing" up the SQL connection within the class makes it difficult to invert the control and make it more unit test friendly.
Another option would be to connect to a dummy database and use that connection. The dummy database would have just enough to allow the test to be exercised as an integration test.
That legacy code should be treated as 3rd party code you have no control over. And you should not waste time testing 3rd part code you have no control over. Common practice is to encapsulate 3rd party code behind an abstraction you do control and use that. The legacy code demonstrates technical debt that is being cashed in with the current difficulties that it is presenting because of poor design.
Not much else can be done given the current restrictions.
The closest I could get was to create an interface named IFake that I would apply to FakeSchedule;
public interface IFake
{
Action GetFakeAction(Action action);
}
public class FakeSchedule : Schedule, IFake
{
public bool TransactionStarted { get; set; }
public Action GetFakeAction(Action action)
{
return () => TransactionStarted = true;
}
}
I then created the following extension method;
public static void Testable<T>(this T obj, Action action)
{
if(obj is IFake)
{
action = ((IFake)obj).GetFakeAction(action);
}
action();
}
This allowed me to call the BeginTransaction method like this;
[TestMethod]
public void BeginTransaction_WhenCalled_SetsTransactionStartedToTrue()
{
Schedule schedule = new FakeSchedule();
var connection = new SqlConnection();
schedule.Testable(schedule.BeginTransaction);
Assert.IsTrue(((FakeSchedule)schedule).TransactionStarted);
}
Obviously this solution is far from ideal but it works, if I'm running a unit test then the call to begin transaction is diverted away from the real implementation.
The version I implement will need some work (my implementation of GetFakeAction is too dumb) but it's the closest I think I am going to get, the only other solution I can see would be to either use Prig or to follow NKosi's answer and connect to a dummy database.
I'm new to Rhino Mocks and mocking in C# though not in general. I'm writing unit tests for a class MyClasswhich internally creates other objects as private fields. I've unit tested those classes separately but not how MyClass interacts with them...
class MyClass
{
public void Method1()
{
var o = new OtherClass();
o.Method2();
o.Method3();
}
}
Note that I don't pass OtherClass as a ctor argument and I don't really want to... creating these objects is something the class does, I don't really want an external agent injecting them.
Does Rhino Mocks allow me to somehow mock OtherClass in this scenario from a unit test, so I can determine instances are created and interacted with correctly?
Disclaimer I work at TypeMock.
It's very simple to fake a future Instance when using Typemock Isolator, actually it can be done in one line :
var classUnderTest = new MyClass();
// Faking future OtherClass
var fakeOther = Isolate.Fake.NextInstance<OtherClass>();
And you can read more about it here.
No, Rhinomocks mocks doesn't support this capability. Rhinomocks/Moq/FakeItEasy/NSubstitute are all proxy based tools which means non of them are able to isolate your code without refactoring.
To be able to isolate without refactoring you need to use code weaving tools such as Typemock Isolator, Msfakes and etc...
Somehow it is not so popular in the community to combine 2 mocking frameworks in the same project, however when I was in the .net world I usually combine Rhinomocks and Msfakes together;
Rhinomocks as a default Mocking framework
Msfakes only where it is necessary(for regular cases Rhinomocks is better....); static/sealed and etc...
Am new to unit testing, and just getting started writing unit tests for an existing code base.
I would like to write a unit test for the following method of a class.
public int ProcessFileRowQueue()
{
var fileRowsToProcess = this.EdiEntityManager.GetFileRowEntitiesToProcess();
foreach (var fileRowEntity in fileRowsToProcess)
{
ProcessFileRow(fileRowEntity);
}
return fileRowsToProcess.Count;
}
The problem is with GetFileRowEntitiesToProcess(); The Entity Manager is a wrapper around the Entity Framework Context. I have searched on this and found one solution is to have a test database of a known state to test with. However, it seems to me that creating a few entities in the test code would yield more consistent test results.
But as it exists, I don't see a way to mock the Manager without some refactoring.
Is there a best practice for resolving this? I apologize for this question being a bit naïve, but I just want to make sure I go down the right road for the rest of the project.
I'm hearing two questions here:
Should I mock EdiEntityManager?
Yes. It's a dependency external to the code being tested, its creation and behavior are defined outside of that code. So for testing purposes a mock with known behavior should be injected.
How can I mock EdiEntityManager?
That we can't know from the code posted. It depends on what that type is, how it's created and supplied to that containing object, etc. To answer this part of the question, you should attempt to:
Create a mock with known behavior for the one method being invoked (GetFileRowEntitiesToProcess()).
Inject that mock into this containing object being tested.
For either of these efforts, discover what may prevent that from happening. Each such discovery is either going to involve learning a little bit more about the types and the mocks, or is going to reveal a need for refactoring to allow testability. The code posted doesn't reveal that.
As an example, suppose EdiEntityManager is created in the constructor:
public SomeObject()
{
this.EdiEntityManager = new EntityManager();
}
That would be something that prevents mocking because it gets in the way of Step 2 above. Instead, the constructor would be refactored to require rather than instantiate:
public SomeObject(EntityManager ediEntityManager)
{
this.EdiEntityManager = ediEntityManager;
}
That would allow a test to supply a mock, and conforms with the Dependency Inversion Principle.
Or perhaps EntityManager is too concrete a type and difficult to mock/inject, then perhaps the actual type should be an interface which EntityManager defines. Worst case scenario with this problem could be that you don't control the type at all and simply need to define a wrapper object (which itself has a mockable interface) to enclose the EntityManager dependency.
I am trying to setup unit tests for my Linq To SQL code. My code uses the System.Data.Linq.Table class (generated by the designer).
Because this class is sealed and the constructor is internal it is completely impervious to unit testing frameworks like Rhino Mocks. (Unless you want to alter you code to use the repository pattern, which I would rather not.)
Typemock can (some how) mock this class. (See here for an example.)
However, Typemock is also $800 a license. I don't see my employer springing for that anytime soon.
So here is the question. Are there any other mocking frameworks out there that don't rely on Interfaces to create the mocks?
Edit: Example of code that I need to test:
public class UserDAL : IUserDAL
{
private IDataClassesDataContext _ctx;
public UserDAL()
{
string env = ConfigurationManager.AppSettings["Environment"];
string connectionString = ConfigurationManager
.ConnectionStrings[env].ConnectionString;
_ctx = new DataClassesDataContext(connectionString);
}
public UserDAL(IDataClassesDataContext context)
{
_ctx = context;
}
public List<User> GetUsersByOrganization(int organizationId)
{
IOrderedQueryable<User> vUsers =
(from myUsers in _ctx.Users
where myUsers.Organization == organizationId
orderby myUsers.LastName
select myUsers);
return vUsers.ToList();
}
public bool IsUserInOrganization(User user, int orgainzationID)
{
// Do some Dal Related logic here.
return GetUsersByOrganization(orgainzationID).Contains(user);
}
}
I have shorted this up to make it easier to read. The idea is that I have some code (like IsUserInOrganization that calls another method (like GetUsersByOrganization) that does a Linq query.
I would like to unit test the IsUserInOrganization method. Do do that I would need to mock _ctx.Users which is a Table class (that is sealed and has an internal constructor).
Check out Microsoft Stubs that has the simple premise of:
Replace any .NET method with your own
delegate!
And a more detailed description of it's capabilities (emphasis is mine).
Stubs is a lightweight framework for
test stubs and detours in .NET that is
entirely based on delegates, type
safe, refactorable and source code
generated. Stubs was designed provide
a minimal overhead to the Pex white
box analysis, support the Code
Contracts runtime writer and
encourage the programmatic models
rather than record/replay tests.
Stubs may be used on any .NET method, including non-virtual/static
methods in sealed types.
There are two standard unit testing approaches in this case:
1) Don't test the platform - if the dependency is on a framework class, you don't write tests where that interaction is verified. This typically means you substitute a dependency at test time, but in your case it likely means you inject the table itself.
2) Wrap the platform - if you need to test something that interacts with the platform, then write a wrapper layer for the relevant components
There's also integration and acceptance testing to consider. For both of these cases you would usually simply accept the dependency as it exists in your application.
What precisely are you concerned about testing that you need to directly mock/substitute this class?
Edit:
It seems as if you're looking to avoid rewriting code to be more testable. This is where TypeMock excels, and is the reason why some test advocates think TypeMock can lead to problems. It is, however, the right tool for the job if you absolutely refuse to restructure your code for testability.
Edit #2:
Perhaps I'm being overly obsessive about this, but let's consider a more testable pattern:
Organization()
{
HasUser(name)
}
OrganizationDAL
{
Organization LoadOrganization(id)
}
OrganizationServiceFacade
{
IsUserInOrganization(name, orgid)
{
return OrgDAL.LoadOrganization(id).HasUser(name)
}
}
Organization's natural contains test for a user no longer needs to be platform-dependent, you should be able to inject the datasource. OrganizationDAL is only responsible for loading organizations rather than returning information about organizations (although there are ways to put queries into this layer if necessary). OrganizationServiceFacade is only responsible for providing composed services, which should both satisfy mockability and avoid the need for extra unit tests (it's an Integration or possibly even an Acceptance target) since it's a wrapper class. Depending on how you construct Organizations, you can inject data without relying on a particular notion of how that data works.
You may want to consider using the Repository pattern, basically it's the "wrap the platform" suggestion from Mike. With it you'll be mocking IRepository rather then the DataContext.
http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx
The class I want to test is my ArticleManager class, specifically the LoadArticle method:
public class ArticleManager : IArticleManager
{
private IArticle _article;
public ArticleManger(IDBFactory dbFactory)
{
_dbFactory = dbFactory;
}
public void LoadArticle(string title)
{
_article = _dbFactory.GetArticleDAO().GetByTitle(title);
}
}
My ArticleDAO looks like:
public class ArticleDAO : GenericNHibernateDAO<IArticle, int>, IArticleDAO
{
public virtual Article GetByTitle(string title)
{
return Session.CreateCriteria(typeof(Article))
.Add(Expression.Eq("Title", title))
.UniqueResult<Article>();
}
}
My test code using NUnit and Moq:
[SetUp]
public void SetUp()
{
_mockDbFactory = new Mock<IDBFactory>();
_mockArticleDao = new Mock<ArticleDAO>();
_mockDbFactory.Setup(x => x.GetArticleDAO()).Returns(_mockArticleDao.Object);
_articleManager = new ArticleManager(_mockDbFactory.Object);
}
[Test]
public void load_article_by_title()
{
var article1 = new Mock<IArticle>();
_mockArticleDao.Setup(x => x.GetByTitle(It.IsAny<string>())).Returns(article1.Object);
_articleManager.LoadArticle("some title");
Assert.IsNotNull(_articleManager.Article);
}
The unit test is failing, the object _articleManager.Article is returning NULL.
Have I done everything correctly?
This is one of my first unit tests so I am probably missing something obvious?
One issue I had, was that I wanted to mock IArticleDao but since the class ArticleDao also inherits from the abstract class, if I just mocked IArticleDao then the methods in GenericNHibernateDao are not available?
Preface: I'm not familiar with using Moq (Rhino Mocks user here) so I may miss a few tricks.
I'm struggling to follow some of the code here; as Mark Seemann pointed out I don't see why this would even compile in its current state. Can you double check the code, please?
One thing that sticks out is that you're injecting a mock of IDBFactory into Article manager. You then make a chained call of:
_article = _dbFactory.GetArticleDAO().GetByTitle(title)
You've not provided an implementation of GetArticleDAO. You've only mocked the LoadByTitle bit that happens after the GetARticleDAO call. The combination of mocks and chained calls in a test are usually a sign that the test is about to get painful.
Law of Demeter
Salient point here: Respect the Law of Demeter. ArticleManager uses the IArticleDAO returned by IDBFactory. Unless IDBFactory does something really important, you should inject IArticleDAO into ArticleManager.
Misko eloquently explains why Digging Into Collaborators is a bad idea. It means you have an extra finicky step to set up and also makes the API more confusing.
Furthermore, why do you store the returned article in the ArticleManager as a field? Could you just return it instead?
If it's possible to make these changes, it will simplify the code and make testing 10x easier.
Your code would become:
public class ArticleManager : IArticleManager
{
private IArticleDAO _articleDAO
public ArticleManger(IArticleDAO articleDAO)
{
_articleDAO = articleDAO;
}
public IArticle LoadArticle(string title)
{
return _articleDAO.GetByTitle(title);
}
}
You would then have a simpler API and it'd be much easier to test, as the nesting has gone.
Making testing easier when relying on persistence
In situations where I'm unit testing code that interacts with persistence mechanisms, I usually use the repository pattern and create hand-rolled, fake, in-memory repositories to help with testing. They're usually simple to write too -- it's just a wrapper around a dictionary that implements the IArticleRepository interface.
Using this kind of technique allows your ArticleManager to use a fake persistence mechanism that behaves very similarly to a db for the purpose of testing. You can then easily fill the repository with data that helps you test the ArticleManager in a painless fashion.
Mocking frameworks are really good tools, but they're not always a good fit for setting up and verifying complicated or coherent interactions; if you need to mock/stub multiple things (particularly nested things!) in one test, it's often a sign that the test is over-specified or that a hand-rolled test double would be a better bet.
Testing is hard
... and in my opinion, doubly hard if you start with mocking frameworks. I've seen a lot of people tie themselves in knots with mocking frameworks due to the 'magic' that happens under the hood. As a result, I generally advocate staying away from them until you're comfortable with hand-rolled stubs/mocks/fakes/spies etc.
As you have currently presented the code, I can't see that it compiles - for two reasons.
The first one is probably just an oversight, but the ArticleManager class doesn't have an Article property, but I assume that it simply returns the _article field.
The other problem is this line of code:
_mockArticleDao.Setup(x => x.GetByTitle(It.IsAny<string>())).Returns(article1.Object);
As far as I can see, this shouldn't compile at all, since ArticleDAO.GetByTitle returns Article, but you are telling it to return an instance of IArticle (the interface, not the concrete class).
Did you miss something in your description of the code?
In any case, I suspect that the problem lies in this Setup call. If you incorrectly specify the setup, it never gets called, and Moq defaults to its default behavior which is to return the default for the type (that is, null for reference types).
That behavior, BTW, can be changed by setting the DefaultValue property like this:
myMock.DefaultValue = DefaultValue.Mock;
However, that's not likely to solve this problem of yours, so can you address the issues I've pointed out above, and I'm sure we can figure out what's wrong.
I am not a Moq expert but it seems to me that the problem is in you mocking ArticleDAO where you should be mocking IArticleDAO.
this is related to your question:
One issue I had, was that I wanted to mock IArticleDao but since the class ArticleDao also inherits from the abstract class, if I just mocked IArticleDao then the methods in GenericNHibernateDao are not available?
In the mock object you don't need the methods inherited from the GenericNHibernateDao class. You just need the mock object to supply the methods that take part in your test, namely: GetByTitle. You provide the behavior of this method via mocking.
Moq will not mock methods if they already exist in the type that you're trying to mock. As specified in the API docs:
Any interface type can be used for mocking, but for classes, only abstract and virtual members can be mocked.
Specifically, your mocking of GetByTitle will be ignored as the mocked type, ArticleDao, offers a (non-abstract) implementation of this method.
Thus, my advise to you is to mock the interface IArticleDao and not the class.
As mentioned by Mark Seeman, I couldn't get this to compile "as-is" as the .GetByTitle expectation returns the wrong type, resulting in a compile-time error.
After correcting this, and adding the missing Article property, the test passed - leading me to think that the core of your problem has somehow become lost in translation as you wrote it up on SO.
However, given you are reporting a problem, I thought I'd mention an approach that will get Moq itself to help you identify your issue.
The fact you are getting a null _articleManager.Article is almost certainly because there is no matching expectation .GetByTitle. In other words, the one that you do specify is not matching.
By switching your mock to strict mode, Moq will raise an error the moment a call is made that has no matching expectation. More importantly, it will give you full information on what the unmatched call was, including the value of any arguments. With this information you should be able to immediately identify why your expectation is not matching.
Try running the test with the "failing" mock set as strict and see if it gives you the information you need to solve the problem.
Here is a rewrite of your test, with the mock as strict (collapsed into a single method to save space):
[Test]
public void load_article_by_title()
{
var article1 = new Mock<Article>();
var mockArticleDao = new Mock<ArticleDAO>(MockBehavior.Strict); //mock set up as strict
var mockDbFactory = new Mock<IDBFactory>(MockBehavior.Strict); //mock set up as strict
mockDbFactory.Setup(x => x.GetArticleDAO()).Returns(mockArticleDao.Object);
mockArticleDao.Setup(x => x.GetByTitle(It.IsAny<string>())).Returns(article1.Object);
var articleManager = new ArticleManager(mockDbFactory.Object);
articleManager.LoadArticle("some title");
Assert.IsNotNull(articleManager.Article);
}