Writing unit tests which depends on other functions in same class - unit-testing

I have to write some unit tests which depends on other unit tests. For an example, there is a function to move files: move_file(). To test that function, first I'm required to create a file using the function save_file() which involves another method in the same class. Calling save_file function involves calling a cpanel UAPI which involves some authentication. So, calling save_file function is essential to create a file. Is it acceptable to write a unittest to move_file() method using save_file() method to create a file?

It sounds like you are calling the cpanel UAPI from your class, so your tests are integration tests, really. Does that make a difference? Of course.
Generally speaking, in order to test something, you have to set up your system in a meaningful way. How to do this depends on what you are testing.
In unit tests, you're testing the subject in isolation. If it depends on something external, like an API, it's best to create an abstraction or a thin wrapper for it. That's something that you can easily mock or fake in your tests.
But even this abstraction or wrapper has to be tested with the real thing at some point. And that's when you can't fake it any more. You can't move a file that does not exist. Given that, it's perfectly acceptable to call another method to bring your test scenario into the right state.

Related

When do I need to implement interfaces for unit testing if I'm using Mockito?

I'm new to unit testing and Mockito. I code to interfaces for best practice but, since I use Mockito, when do I actually need to implement those interfaces for unit testing? Would I only need this if I'm looking for default values different than the ones Mockito mocks provide?
Thanks!
You only "need" an implementation of the class under test ("system under test"). Any collaborators -- which may appear as either injected fields in your class under test, or as parameters to the methods you are calling on your class under test -- may be left as mocked interfaces.
However, the less real objects you use, the more complicated your test becomes as you have to re-write all of the expected behavior for those collaborators as "when(...)" statements. In essence, you practically end up writing the application code a whole second time as the "when(...)" statements.
I try to mock only "deep" objects that have a long chain of dependencies required in order to produce the test scenario I am trying to create. Things like entity classes, transfer objects, etc., should rarely be mocked, and hence they should usually be implemented. Other kinds of objects are a gray area.
Ultimately, you will always want to make sure your actual implementation classes are tested, otherwise there is no point to the test.

Unit test wrapper objects?

I try to use TDD as much as I can. When I do, I stowe all comunication with the outside away in wrapper classes. A few minutes ago, I made a wrapper for the static class Directory, so I can test my other code without talking to the actual file system.
But what about unit testing the wrapper itself? Since I use TDD, it nags me that I haven't written tests for it. On the other hand, It is a wrapper and nothing else, so do I really need to?
I tend to do the same and not worry about unit testing wrapper classes, as long as I've satisfied myself that they contain the bare minimum amount of code. If, as in your case, I were calling a number of methods on the Directory class, I'd create an interface containing each of the methods I'd be using to ensure that I'm able to test as much of the behaviour of my system under test as possible.
As long as you are using integration and/or acceptance tests as well, it's fine not to unit test your wrapper classes directly. If you try to test Directory directly it's an integration test anyway. I would ask myself whether I had an automated test at some level that would fail if I were to remove the interaction with the Directory class from my code.
Bear in mind that the reason you're normally forced to write wrapper classes is because the code you're trying to test is not inherently testable and is a dependency that cannot be mocked out. Creating the wrapper class allows that behaviour to be mocked out.

How to write Unit Test for manager running dao?

I'm having a simple test design problem, which I would like to solve once and for all.
I'm pretty used to regular Java design pattern where there is some Manager interface (or facade) and a set of DAO interfaces. Concrete implementation of ManagerImpl is using concrete implementations of DaoImpl.
Right now I'm at the point of implementation, where I don't have a database connected to my project yet, so I guess this is a perfect time to write proper unit tests without DB :-)
I was able to mock some methods of my manager by using mockito, but since the Test Under Method (or so called System Under Test) is using DAO internally, I would have to mock the DAO as well. Unfortunately I cannot do that without setting concrete DAO implementation in my manager, like myManager.setMyDao(mockedDao), but now I would have to pull out this setMyDao method into interface, which of course breaks encapsulation and makes my clean and perfect interfaces look like garbage.
So the question is: How to mock DAO in tests while preserving clean Manager-Dao architecture?
You should unit test concrete implementations, i.e. ManagerImplTest, which will explicitly create ManagerImpl and therefore you have all setMyDao methods available for mocks. Your test will not know about Manager interface.
BTW, it is not always necessary to create interfaces for everything. In most cases only single implementation of managers and daos will exist. If there is no any other strong reason (e.g. Spring AOP proxies or dependency separations), I guess it's better don't create interfaces for everything in sake of simplicity.
You can get rid of set methods altogether and inject factory. This way no extra method is exposed (in fact, no extra method even exists) and problem disappears. Then in test you configure factory mock to return DAO mocks and from that point on it's plain and simple.

Mock Objects vs Test Database

What's the advantage of using mock objects in comparison to a static test database that has known data and using transactions to make sure nothing changes when testing against the database.
You can do both. Use mock objects to test you BLL logic and then use a test database to test your DAL logic. That way if something breaks you can easily see where the problem lies by which test fails.
Firstly, using a mock will be much quicker than connecting to an external database. However the main reason is that mocks behave the same each time the test is run, which you can't guarentee with an external service like a database, which means unit tests don't fail randomly. You can also easily simulate any types of failure you want to handle with a mock object.
It's also a good idea to run integration tests against a real database however to test things like configuration and performance.
If you can ensure that the static test db doesn't change during testing then I think static test db is better than mock objects. But, then it depends on what you want to test and the complexity of the code being tested. I would go with mock objects as they are simpler to maintain compared with a db.
Imagine you're about to write a class which doesn't exist. Maybe it's a controller. It's not something which talks straight to the database.
You have a good idea of how it ought to behave, and you know what it should be responsible for, and what it should delegate to some other service (using Single Responsibility Principle). So you write interfaces to represent the roles of the helper classes it's going to use.
Then you write an example of how you might use your class that you're about to create. If you like, you can call the example a unit test. You mock out the interactions with the helper classes. When you run the example, it fails, because you haven't written the code yet. You can now write the code to make it pass, using the interfaces of the helper classes - which you also haven't written yet.
Then you do the same with the helper classes, mocking out their helpers.
Eventually you'll reach a class which talks to the database. Or maybe it talks to a web service. Or perhaps the data is static, or in memory. (It doesn't matter to the original class, because your class is decoupled from this).
At this point you'll want an example to describe the behaviour of this class, too, and if it's a database connector, you'll need a database for the example.
Writing code this way produces code that's easy to use and understand, with nothing extra that isn't needed by something further up the stack. This is usually more robust than code that's easier to write. That's why we sometimes use mocks - because writing tests first using mocks helps produce good, maintainable, decoupled design.
Usually you would use both of these approaches.
For unit tests you would use mocked objects. This way you can test your system in a much more fine-grained way, because you can mock every object - not only the ones that wrap the database connection. In general it is good practise to unit test every class in separation of all the dependencies. The benefits are - its is possible to test all the error handling on all levels and make sure you test all the code paths, when you get a test failure you can immediately find the cause, etc.
For integration and end-to-end tests you test big parts of the system or the whole thing. Then you would connect to the database (because this connection is part of the test). Obviously you have to ensure that the database is in a known state, etc., etc.
You will end up having much more unit tests than integration tests, so its actually quite important to make them very quick - yet another advantage of using mock objects.
The setup for testing with a db can be arduous. If you find yourself spending more time in setting up the db, just to test some functional aspect of your business logic, then you might want to use a mock/fake.

Why would I write a fake class and unit test it?

I understand the need to test a class that has logic (for instance, one that can calculate discounts), where you can test the actual class.
But I just started writing unit tests for a project that will act as a repository (get objects from a database). I find myself writing a 'fake' repository that implements an ISomethingRepository interface. It uses a Dictionary<Guid, Something> for storage internally. It implements the Add(Something) and GetById(Guid) methods of the interface.
Why am I writing this? Nothing I'm writing will actually be used by the software when it's deployed, right? I don't really see the value of this exercise.
I also got the advice to use a mock object that I can setup in advance to meet certain expectations. That seems even more pointless to me: of course the test will succeed, I have mocked/faked it to succeed! And I'm still not sure the actual software will perform as it should when connecting to the database...
confused...
Can someone point me in the right direction to help me understand this?
Thank you!
You are not testing your mock object but some other class that is interacting with it. So you could for example test that a controller forwards a save method call to your fake repository. There is something wrong if you are "testing your fake objects"
Don't test the mock class. Do test the production class using the mock class.
The whole point of the test support class is to have something that you can predict its behavior. If you need to test the test support class in order to predict its behavior, there is a problem.
In the fake database article you linked in a comment, the author needs to unit test his fake database because it is his product (at least in the context of the article).
Edit: updated terms to be more consistent.
Mock - created by mocking framework
Fake - created manually, might actually function some.
Test Support - Mocks, Fakes, Stubs, and all the rest. Not production.
The purpose of the mock/stub object is not to be tested instead of the unit you're trying to test, it's to allow you to test that unit without needing other classes.
It's basically so that you can test classes one at a time without having to test all the classes they're also dependent on.
You should not be testing the mock class.
What you normally do is: you create mock classes for all the classes that the class you are testing interact with.
Let's say you are testing a class called Bicycle which takes in the constructor objects of classes Wheel, Saddle, HandleBar,etc.
And then within the class Bike you you want to test test its method GetWeight which probably iterates through each part and calls property/method Weight of them and then returns the total.
What you do:
you write a mock class for each part
(Wheel, saddle etc) which simply
implements the Weight bit
then you pass those mock classes to the Bicycle
test the GetWeight method on the Bicycle class
It that way you can focus on testing the GetWeight on the Bicycle class, in a manner that is independent on other classes (say they are not implemented yet, not deterministic etc.)
Who watches the watchers?
It is interesting for example if the mock implementation throws specific Exceptions for the corner cases, so you know that the classes that use or depend the IRepositorySomething can handle the exceptions that are thrown in real life. Some of these exceptions you can't generate easily with a test database.
You do not test the Mock object with a unit test, but you use it to test classes that depend on it.
Instead of writing a fake class by yourself, you can use a tool (like Rhino or Typemock) to mock it. It is much easier than writing all the mocks yourself. And like others said, there's no need to test fake code, which is no code if you use the tool.
I have actually found two uses for the mock classes that we use in repository implementation testing.
The first is to test the services that use an implementation of the "ISomethingRepository" equivalent that you mention. However, our repository implementations are created by a factory. This means that we do write tests against the "ISomethingRepository", but not against the "MockSomethingRepository" directly. By testing against the interface, we can easily assert that the code coverage for our tests cover 100% of the interface. Code reviews provide simple verification that new interface members are tested. Even if the developers are running against the mock that the factory returns, the build server has a different configuration that tests against the concrete implementation that the factory returns within the nightly builds. It provides the best of both worlds, in terms of test coverage and local performance.
The second use is one that I am surprised that no one else has mentioned. My team is responsible for the middle tier. Our web developers are responsible for the front end of the web products. By building out mock repository implementations, there is not the artificial obstacle of waiting for the database to be modeled and implemented prior to the front-end work starting. Views can be written that will be built off of the mock to provide a minimal amount of "real" data to meet the expectations of the web developers, as well. For example, data can be provided to contain minimum and maximum length string data to verify that neither break their implementation, etc.
Since the factories we use are wired as to which "ISomethingRepository" to return, we have local testing configurations, build testing configurations, production configurations, etc. We purposely are trying to make sure that no team on the project has unreasonable wait times because of another team's implementation time. The largest chunk of wait time is still provided by the development team, but we are able to crank out our domain objects, repositories, and services at a faster pace than the front-end development.
Of course, YMMV. ;-)
You write "fake" class called Stub or Mock object because you want to test an implementation in a simple way without testing the real concrete class. The purpose is to simplify the testing by testing only the Interface (or abstract class).
In your example, you are testing something that has a dictionnary. It might be fill up in real by the database or have a lot of logic behind it. In your "fake" object, you can simplify everything by having all data constant. This way you test only the behavior of the interface and not how the concrete object is built.
There is generally no need to run classical unit tests in the Data Access Layer.
Perhaps you can write integrational style unit test for your Data Acess Classes, that is, Integration Test (= integrating your Data Access Layer Code with the DB) using the features of Unit Testing Frameworks.
For example, in a Spring project you can use Spring Testcontext to start your Spring context inside a unit test, and then connect to a real database and test that the queries returns correct results. You need probably an own database for unit tests, or perhaps you can connect them with a developer DB.
Have a look at the following article for a good explanation of this:
https://web.archive.org/web/20110316193229/http://msdn.microsoft.com/en-us/magazine/cc163358.aspx
Basically, if you write a fake object and it turns out to be fairly complex, it is sometimes worth it to unit test the fake to make sure it works as expected.
Since a repository can be complex, writing unit tests for it often makes sense.