I’ve seen lots of info on this topic but wanted to provide a specific example and ask some specific questions.
I’m currently in the middle of a development project in which I’m programming against a telephony system via the OEM provided SDK. I’ve created several interfaces & classes that extend the functionality of the SDK and have refactored these to support dependency injection for ease of testing. At the lowest level, I have methods like “retrieveUserInfo” that accepts a connection interface and a query object.
When Unit testing, I could actually create a connection to the telephony system, get back a given user, and check it for the correct data. This test is meaningful to me as it lets me know both my Middleware and the underlying OEM libraries are working correctly; however, because it’s actually creating a connection to an outside system, it seems more like an integration test to me (the test will fail if you can’t connect to the telephony system, a user is not configured as expected, I have some bug in my business logic, or there is an issue with the underlying libraries).
Should this test be labeled as an integration test? If so, how would I go about attempting to unit test methods like “retrieveUserInfo”? How do I properly segment these 2 types of tests?
Defining what a 'unit' is, is quite difficult. But if what you're testing is putting calls on external libraries that actually call to different systems, then you're definitely in the realm of integration testing.
What a unit is limited to is a bit subjective, but might be restricted to a class or public method on a class.
If you want to unit test a method that calls methods on an external dependency, then that's something you want to mock or stub (see Moq for a good mocking library).
Related
I have a C# library that gets data from public api.
trying to get into TDD and was wondering how to unit test a library that the main focus of it is to get data from the server and convert the json to .net objects. (Basically handling the http requests along with limiting and error handling and some configuration settings)
I know you should mock some sort of database but not sure how exactly. And i've read that the tests should run all the time even with internet connection off.
You can implement only integration testing. You also can test your code with internet connection off - just create a kind of wrapper. Among various design patterns the most appropriate is Facade for this kind of task. Create Facade around third-party library so you can mock this facade in future and make it produce desired/undesired results so you can unit test your classes. But:
Don't test or mock what you don't own
I am having difficulties while trying to understand the purpose of mocking my WCF applications in unit tests. I have read this article Testing with mock objects and I believe I got the idea why we use mocking in standard application - it is better to test behaviour rather than implementation of the method. So with using Mock objects, I can test whether certain method called certain mock object, whether it changed some properties etc.
But while I was searching for some good ways how to test WCF, everyone was suggesting to use Mocking as well. The thing is, that I feel like I should test whether method (which is communication with service) is really able to reach the service and obtain result, that is satisfactory...which is not the case I will achieve using mock object.
Question:
Is using mock objects in my WCF app unit tests really intended to test only whether the method tried to call the OperationContract(method) exposed by service (while not expecting the real results)?
Or am I missing something?
The purpose of Unit Testing is not to test your application, but to make sure the code you've written is doing what is intended and subsequently let you know when you've made a simple coding goof. When it comes to testing for communication-based services, there are a dozen other factors, not the least of which being actual connectivity, that could affect your connection but not actually tell you anything useful about your code. Thus, you should rely on running debug runs of your application to test end-to-end functionality, and Unit Tests with those mocks to test the actual code functionality.
Will you miss something here and there? Yes, but the definition of good Unit Tests is such that you'll eventually have to touch them up when this happens.
I would like to create unit tests for data dependent code. For example:
A user class that has the usual create, update & delete.
If I wanted to create a test for "user already exists" scenario, or and update or delete test. I would need to know that a specific user already exists in my database.
In such cases, what would be the best approach to have stand alone tests for these operations that can run in any order?
When you have dependencies like this think about whether you want to be Integration Testing as opposed to Unit Testing. If you do want to do Unit tests take a look at using Mock Data.
Integration Testing:
Tests how you code integrates with different parts of a system. This can be making sure your code connects to a database properly or has created a file on the filesystem. These tests are usually very straight-forward and do not have the same constraint of "being able to run in any order." However, they require a specific configuration in order to pass which means they do float well from developer to developer.
Unit Testing: Tests your code's ability to preform a function. For example "Does my function AddTwoNumbers(int one, int two) actually add two numbers?" Unit tests are to ensure any changes in code does not effect the expected results.
When getting into areas like "Does my code call the database any enter the result correctly?" you need to consider that unit tests are not meant to interact with the system. This is where we get into using "mock data." Mock classes and mock data take the place of an actual system to just ensure that your code "called out in the way we were expecting." The difficult part about this is it can be done but most of the .Net Framework classes do not provide the needed Interfaces in order to do it easily.
See the MSDN page on Tesing for more info. Also, consider this MSDN article on Mock Data.
I am currently working on a c# project which makes use of an SQLite Database. For the project I am required to do unit testing but was told that unit testing shouldn't involve external files, like database files for the testing and instead the test should emulate the database.
If I have a function that tests if a something exists in a database how could this sort of method be tested with a unit testing.
in general it makes life easier if external files are avoided and everything is done in code. There are no rules which says "shouldn't", and sometimes it just makes more sense to have the external dependency. But only after you have considered how not to have it, and realized what the tradeoffs are.
Secondly, what Bryan said is a good option and the one I've used before.
In an application that uses a database, there will be at least one component whose responsibility is to communicate with that database. The unit test for that component could involve a mocked database, but it is perfectly valid (and often desirable) to test the component using a real database. After all, the component is supposed to encapsulate and broker communication with that database -- the unit test should test that. There are numerous strategies to perform such unit tests conveniently -- see the list of related SO questions in the sidebar for examples.
The general prescription to avoid accessing databases in unit tests applies to non-database components. Since non-database components typically outnumber database-related components by a wide margin, the vast majority of unit tests should not involve a database. Indeed, if such non-database components required a database to be tested effectively, there is likely a design problem present -- probably improper separation of concerns.
Thus, the principle that unit tests should avoid databases is generally true, but it is not an absolute rule. It is just a (strong) guideline that aids in structuring complex systems. Following the rule too rigidly makes it very difficult to adequately test "boundary" components that encapsulate external systems -- places in which bugs find it very easy to hide! So, the question that one should really be asking oneself when a unit test demands a database is this: is the component under test legitimately accessing the database directly or should it instead collaborate with another that has that responsibility?
This same reasoning applies to the use of external files and other resources in unit tests as well.
With SQLite, you could use an in-memory database. You can stage your database by inserting data and then run your tests against it.
Once databases get involved it always blurs the line between unit testing and integration testing. Having said that, it is always a nice and very useful test to be able to put something in a database (Setup), Do your test and remove it at the end (Cleanup). This lets you test end to end one part of your application.
Personally I like to do this in an attribute driven fashion. By Specifying the Sql scripts to run for each test as an attribute like so ..
[PreSqlExecute("SetupTestUserDetails.sql")]
[PostSqlExecute("CleanupTestUserDetails.sql")]
public void UpdateUserNameTest()
{
The connectionstrings come from the app.config as usual and can even be a symbolic link to the app.config in your main project.
Unfortunately this isn't a standard feature with the MS test runner that ships with visual studio. If you are using Postsharp as your AOP framework, this is easy to do. If not, you can still get the same functionality for standard MS Test Runner, by using a feature of .Net called "Context Bound Objects". This lets you inject custom code into an object creation chain to do AOP like stuff as long as your objects inherit from ContextBoundObject.
I did a blog post with more details and a small, complete code sample here.
http://www.chaitanyaonline.net/2011/09/25/improving-integration-tests-in-net-by-using-attributes-to-execute-sql-scripts/
I think is really bad idea to have unit tests that depends on database information.
Also I think is a bad idea to use sqlite for unit tests.
You need to test objects protocol, so if you need something in your tests you should create them somewhere in the tests (usually at setUp).
Since is difficult to remove persistence, the popular way to do it is using SQLite, but always create what you need in unit tests.
check this link Unit Tests And Databases this will be more helpful I think
It's best to use a mocking framework, to mimic a database. For C# there is the Entity Framework. Even the use of sqlite is an outside dependency to your code.
I've implemented a subscribe/publish (for my own enjoyment) WCF service which works reasonably well. Like all blogs and books I've seen they all use OperationContext to get the clients callback address. After a bit of reading, due to many people saying not to use OperationContext, I found myself not being able to create proper unit tests. Yet I haven't been able to find an alternative. I suppose the subscribe method could accept a parameter for it to provide its own address? I could see the code being testable from an intergration test stand point of view but not for unit testing since OperationContext would always be null.
How do I get the clients endpoint when they subscribe to my service without using OperationContext?
Little bit of an aside but where is a good WCF resource with testing in mind when showing code samples? There are tons of blogs out there reiterating the same code without providing sample test cases.
Thank you.
Microsoft developers really like sealed and static keywords (as well as internal) and they hate virtual. Because of that standard testing approaches and framworks often don't work. You have two choices:
Wrap access to OperationContext in custom class and inject an instance of the class to your service. This will involve additional work because you will need to do injection somewhere outside your service. For example constructor injection will need custom IInstanceProvider.
Use more poweful testing framework. Check Moles framework which is able to intercept calls and redirect them. This enables "mocking" sealed classes and static methods/properties.
Another approach is simply refactoring your code. Take away all business logic from your service into separate testable business class and let the service participate only in integration test. Service is more like infrastructure and not everything really needs unit test. Integration / end-to-end / behavior test is also test and valid approach.