Which object should I mock? - unit-testing

I am writing a repository. Fetching objects is done through a DAO. Creating and updating objects is done through a Request object, which is given to a RequestHandler object (a la Command pattern). I didn't write the DAO, Request, or RequestHandler, so I can't modify them.
I'm trying to write a test for this repository. I have mocked out both the DAO and RequestHandler. My goal is to have the mocked RequestHandler simply add the new or updated object to the mocked DAO. This will create the illusion that I'm talking to the DB. This way, I don't have to mock the repository for all the classes that call this repository.
The problem is that the Request object is this gob of string blobs and various alphanumeric codes. I'm pretty sure XML is involved too. It's sort of a mess. Another developer is writing the code to create the Request object based on the objects being stored. And since RequestHandler takes in Requests and not the object I'm storing, it can't update the mocked DAO.
So the question is: do I mock the Request too, or should I wait until the other guy, who is kind of slow, to finish his code before I write the test? Or screw it and mock out the entire repository when testing the classes that call the repository?
BTW, I say "mock" not in the NMock sense, but rather like faking the DB with an in-memory collection.

To test the repository I would suggest that you use test doubles for all of the lower layer objects.
To test the classes that depend on the repository I would suggest that you use test doubles for the repository.
In both cases I mean test doubles created by some mocking library (fakes where that works for the test, stubs where you need to return something to the object under test and mocks if you really have to).
If you are creating an implementation of the DAO using in-memory collections to functionally replace the database in a demo or test system that is different to unit testing the upper layers. I have done something similar so that I can give prototypes to people and concentrate on business objects not the physical model. That isn't for unit testing though.

You may of may not be creating a web application, but you can have a look at the NerdDinner application which uses Repository. It is a free PDF that explains how to create an application using ASP.NET MVC and can be found here: Professional ASP.NET MVC 2.0

Related

How to unit test .NET api core controller with injected dependencies which also have dependencies with MOQ or Fake?

I implemented an api controller that will be used by part of another system, rather than users directly. However, I want to provide a unit test for it. I started looking at MOQ and then I realized my particular case is a little more complex. The code works, but as I said, Im trying to make a test for it, without (ideally) writing any data to the Db.
The structure of the classes look like this
api controller
|__MyCustomClass (injected via startup along with configuration)
|__UtilityClass (method: ImportSomeDataFromaFolder)
|__MydataRepositoryClass
|__CustomDerivedDbContext
(override savechanges etc so as to capture EF errors)
Note:
- The return value of the api method is a complex JSON object.
- Id like to have a test that avoids actually writing to the Db
- I am creating a custom DbContext (CustomDerivedContext) and overriding savechanges, so as to capture EF entities that change via in a list, eg. List<EntityEntry>
- The method ImportSomeDataFromaFolder, after parsing the data into POCO objects and sending them to the Repository for persisting to the Db, then moves the file to a different folder. When testing, i'd rather this didnt happen, but rather just load a file to parse.
There are 3 primary things to test:
(1) Does the data in the file get loaded into POCO objects
(2) Do the POCO objects get translated correctly to EF model entities
(3) Does the api return a JSON object that contains the expected results
Or, am I making things more complicated than what should be done for a unit test. I want to write a test against the api controller, but its the CustomDerivedDbContext that seems I want to use a fake here, since I could then remove the step that actually calls the underlying DbContext savechanges.
Sounds like you have tight coupling to implementation concerns that make unit testing your subject in isolation difficult.
That should be seen as a code smell and an indication that the current design choice need to be reviewed and refactored where possible.
If unit testing the API controller then ideally all you should need is a mock of the explicitly injected abstractions.
The API controller need not know anything about the dependencies of its dependencies if proper separation of concerns are followed.

EF4.1 DbSet vs. EF4 ObjectContext and Unit Testing

I currently have a project I've started with EF4, and am going back and adding in unit testing after the fact. I am using the EF4 POCO T4 templates with my model (database) first context. I am using generic repositories for my DAC logic, and unit of work pattern for persistence.
However, I'm running into some issues understanding how to mock up the ObjectContext/ObjectSet. I looked at using the FakeObjectSet<T> sample from this article, but it still leaves a few things out, such as auto-incrementing identities and transaction rollbacks.
So, I'm trying to find a good EF design that will still be fully unit testable.
My question is, does EF4.1 DbSet solve a lot of the issues w/ unit testing EF4? Are there any good comprehensive articles for designing EF4.1 solutions that are fully testable?
Also, keep in mind that I need a model-first solution.
Thanks in advance.
Fully simulating behavior of mocked layer is not point of unit testing. The point of unit testing is believing that mocked layer simply works. Unit test verifies the tested method not the mock. You will just verify that correct method on the mock were called and perhaps you will set up some callbacks for modifying passed data if your business logic expects some values. Example:
You have a business method inserting the record to the database and using the entity and its Id after insertion. The IObjectSet mock will be configured to:
Set expectation that AddObject was called only once - you can set the expected instance in the verification
You can define callback for AddObject to set Id to some value and use it later in the test
DbSet will not make any difference - it is just wrapper around ObjectSet with similar behavior. In my opinion there is no efficient way to make mocks behave as real EF. The effort needed for creating mock with behavior simulating EF + database will be much bigger then effort for your whole application! That will not be mock anymore it will be fake EF provider.
If you want to test your EF code (mapping, querying, persisting) and database behavior (like auto-increment, transactions, etc) you have to write integration tests. Here you have some related questions discussing repositories, unit of work and challenges with testing:
ASP.NET MVC3 and Entity Framework Code first architecture
Organizationally, where should I put common queries when using Entity Framework Code First?

Mock Repository vs. Real Repository w/Mocked Data

I must be doing something fundamentally wrong.
I am implmenting my repositories and then testing them with mocked data. All is well.
Now I want to test my domain objects so I point them at mock repositories.
But I'm finding that I have to re-implement logic from the 'real' repositories into the mocks, or, create 'helper classes' that encapsulate the logic and interact with the repositories (real or mock), and then I have to test those too.
So what am I missing - why implement and test mock repositories when I could use the real ones with mocked data?
EDIT: To clarify, by 'mocked data' I do not hit the actual database. I have a 'DB mock layer' I can insert under the real repositories that returns known-data.
Maybe your mixing your abstractions. maybe some of the helpers and logic that your talking about should be in your domain objects. Your repositories should be implementing a CRUD interface. So your domain logic should be using 8 actions from the repository. Good retrieve and Bad retrieve (exception thrown) are only two of the eight. One test, is how is the Bad retrieve handled in the domain object. The rest of the tests should be testing a Good retrieve.
Unit testing is meant to minimize the tested element -> test data route, in order to reduce search time if a bug occurs - the bug is either in the routine you test or the test unit and nothing else (well, maybe the OS or the compiler... but these are very rare).
Now imagine you made a database accessor module. The module seems to work ok. Then you make a config reader that reads from the database. Instead of a mock database accessor module unit test, you use your real database module on top of mock config data in the database test unit. It still seems to work OK. Now you add a GUI layer that uses the config object returned by the config reader unit. Instead of mocking the "boiled" config data you use the real module which apparently works.
And now your GUI stops working for a certain value. Where is the error? In the GUI, in the config reader, in the database accessor or in the values in the mock database?
In other words, you're not just testing the code you're writing, you're testing the real repository system as well, and if a bug is found you have an additional layer to analyze.
why implement and test mock
repositories when I could use the real
ones with mocked data?
I guess it really comes down to how much code coverage you think you need to have. If you feel the repository is sound and you can use it for testing, go for it. Perhaps the repository unit tests can be run prior to the mock database unit tests, so that you can use the real repositories for testing and feel confident that the testing is still valid.

Unit testing - testing in isolation

I've got a set up with a number of layers:
Website
Application / Service
Domain (contains entities)
Persistence (contains repositories)
I'm testing the persistence layer in isolation OK using data created in memory from a stub object.
Now, Im thinking about testing my Website layer. I know I should be testing it in isolation which Im thinking means creating a stub for the Application layer object it uses but this stub would need its own set of in memory data, duplicated in the stub in the persistence layer and I dont want to do duplicate this and manage it.
So my question is should the subject under test always work with stub objects from the layer below in order to be isolated and do they normally have their own set of data? Or is OK for my web method under test to call a lightweight object in the Application Layer which calls the Persistence layer with stub data?
Thanks for your help. This feels like the last bit of the puzzle for me ...
Ideally in unit testing each subject under test is isolated from its dependencies. You do not want to think your subject under test is broken because one of its dependencies broke and caused the subject under test to fail. If you test like this, you might spend a lot of time tracking down bugs in the wrong place.
Testing how things operate together is the domain of integration testing, not unit testing
Or is OK for my web method under test to call a lightweight object in the Application Layer which calls the Persistence layer with stub data?
If you do this, I wouldn't call the test a unit test in isolation anymore - if the test fails, where is the bug? - but an integration test. Don't misinterpret me, integration testing is fine too, it just has another purpose. But if your goal is to unit test the website layer in isolation, you should mock/stub direct dependencies.
Setting up test data can be tedious task. If you are using DotNet you can make use of a library called NBuilder to generate test data very easily and quickly. It supports a nice fluent interface. You can read more about it here.

Strategies for Using Mock Objects when Unit Testing DAOs

I am curious what strategies folks have found for unit testing a data access class that does not involve loading (and presumably unloading) a real database for each test method? Are you using mock objects to represent the database connection? If so, are you required to pass the mock object into every method-under-test, and thus forcing the API to require a real db connection as a parameter to every method? Or, are you passing a mock object into the constructor at setup()?
I have a class that is implementing what I believe is a Data Mapper (or maybe gateway) pattern. It is the class responsible for encapsulating SQL and returning (or saving) "business objects". The rest of the code can interact with this mapper layer and the business objects, with total disregard for the persistence model. This code needs to have/maintain, or just know about, a live db connection in the real system. Emulating this under test is tricky.
The problem is how to unit test one of these mapper classes. The practice for creating a unit test under xUnit that I have seen most often is using the setup() method of the test to instantiate the SUT (system under test), usually your object that you're testing, and store it in a local variable in the test class. Then each of your test methods, interact with a unique instance of that SUT.
The assumption though is that whatever you're doing in the setup() method will presumably be replicated somewhere in your real code. So, you have to think about the setup process as "is this something I will want to repeatedly reproduce every time I need to use this object in the real world." If I am passing a db connection into the mapper's constructor in the setup that's fine, but doesn't that mean I'll have to pass a live db connection into the mapper object's constructor every time I want to really use one? Imagine that you'll have all kinds of places where you need to retrieve or store a business object and that to use a data mapper object, you need to pass in the db connection every time?
In my case, I am trying to establish tests for these data mapper objects that achieve the following:
Do not require the database connection object to be instantiated and passed into every method of the mapper class.
Do not require that the test case either connect to a real db or create a real, but "test", db on the fly for each test method.
I have basically seen two suggestions, pass the connection object as a parameter (which I have already addressed) or extend the SUT class just for the test and override whatever db connection setup process you have in the real world to use a mock system instead.
I am curious if anyone else is facing these issues, with any language, and what you have done to solve them? Maybe there is something obvious that I am missing?
In my experience, the responsibility for connection to a database is a sore point in data access. I solved this by letting the DAO take care of that based on the configuration file (app.config, etc). This way I don't need to worry about that when I write my tests. The DAL keeps one or more database connection profiles and connects/disconnects on every data access because in the end the connection pool will take care of physically connecting/disconnecting.
Another thing that helped me was using dbUnit to load baseline data before running the tests. I found it easier to go straight to the database instead of using mock objects. Also by connecting to a real database I can (to a certain point) test concurrency by issuing commands in different threads - mock objects wouldn't give me the real behavior.
You can use DbUnit to test SQL
It depends on what you're really trying to test. If you want to test that your SQL does what you expect, that's really heading into Integration Test territory. Assuming you're using Java, there are several pure-java RDBMS solutions (Apache Derby, HSQLDB, H2) you can use for that.
If on the other hand you're really just testing your Java <-> JDBC code (i.e. reading from ResultSets), then you can mock out pretty much all the relevant parts of JDBC since they're mostly interfaces. JMock is great for this. Simply add a setConnection() method to your Class Under Test, and pass in the mocked java.sql.Connection that will do your bidding. This works really well for keeping tests short and sweet.
Depending on how complex is your database setup, it might be a great option using an in memory store.
Normally I do my unit testing with a in-memory SQLite session. This is full blown database 100% in memory, no files, no config needed. Just one line.
Now this is not always an option. SQLite does not support all sql features of full blown server databases. Normally I use a layer trying to make my code database independent. In those cases I just switch to a in-memory database instance which I quickly create/destroy in memory during every setUp/tearDown.
Are you using any mid-layer to access your database? In most cases the greatest benefit of using that type of middleware is not database portability, but a simplified test harness.