am trying to understand using Mock unit testing and i started with MOQ . this question can be answered in General as well.
Am just trying to reuse the code given in How to setup a simple Unit Test with Moq?
[TestInitialize]
public void TestInit() {
//Arrange.
List<string> theList = new List<string>();
theList.Add("test3");
theList.Add("test1");
theList.Add("test2");
_mockRepository = new Mock<IRepository>();
//The line below returns a null reference...
_mockRepository.Setup(s => s.list()).Returns(theList);
_service = new Service(_mockRepository.Object);
}
[TestMethod]
public void my_test()
{
//Act.
var myList = _service.AllItems();
Assert.IsNotNull(myList, "myList is null.");
//Assert.
Assert.AreEqual(3, myList.Count());
}
Here is my question
1 . In testInitialize we are setting theList count to 3(string) and we are returning the same using MOQ and in the below line we are going to get the same
var myList = _service.AllItems(); //Which we know will return 3
So what we are testing here ?
2 . what are the possible scenarios where the Unit Testing fails ? yes we can give wrong values as 4 and fail the test. But in realtime i dont see any possiblity of failing ?
i guess am little backward in understanding these concepts. I do understand the code but am trying to get the insights !! Hope somebody can help me !
The system under test (SUT) in your example is the Service class. Naturally, the field _service uses the true implementation and not a mock. The method tested here is AllItems, do not confuse with the list() method of IRepository. This latter interface is a dependency of your SUT Service therefore it is mocked and passed to the Service class via constructor. I think you are confused by the fact that AllItems method seems to only return the call from list() method of its dependency IRepository. Hence, there is not a lot of logic involved there. Maybe, reconsider this example and add more expected logic for the AllItems method. For example you may assert that the AllItems returns the same elements provided by the list() method but reordered.
I hope I can help you with this one.
1.) As for this one, your basically testing he count. Sometimes in a collection, the data accumulates so it doesn't necessarily mean that each time you exectue the code is always 3. The next time you run, it adds 3 so it becomes 6 then 9 and so on.
2.) For unit testing, there are a lot of ways to fail like wrong computations, arithmetic overflow errors and such. Here's a good article.
The test is supposed to verify that the Service talks to its Repository correctly. We do this by setting up the mock Repository to return a canned answer that is easy to verify. However, with the test as it is now :
Service could perfectly return any list of 3 made-up strings without communicating with the Repository and the test would still pass. Suggestion : use Verify() on the mock to check that list() was really called.
3 is basically a magic number here. Changes to theList could put that number out of sync and break the test. Suggestion : use theList.Count instead of 3. Better : instead of checking the number of elements in the list, verify that AllItems() returns exactly what was passed to it by the Repository. You can use a CollectionAssert for that.
This means getting theList and _mockRepository out of TestInit() to make them accessible in a wider scope or directly inside the TestMethod, which is probably better anyways (not much use having a TestInitialize here).
The test would fail if the Service somehow stopped talking to its Repository, if it stopped returning exactly what the Repository gives it, or if the Repository's contract changed. More importantly, it wouldn't fail if there was a bug in the real implementation for IRepository - testing small units allows you to point your finger at the exact object that is failing and not its neighbors.
Related
I have a hard time to grasp how to implement unit tests in a class where all my fields are private.
The class is calculating a user's position with BLE and CoreLocation - not that important. I have a protocol, which when a new location is found I'm calling it and all the classes which conform to that protocol will receive a room id and room name. So, what that means is that literally all the fields in my class are private, because yeah, there's no reason any outside class should access them right? But that also means I can literally test nothing in that class, even though there are quite a few functions which I would like to test. I mean, I could just make the variables internal instead of private, but it just seems wrong to do that just to unit test. I've heard about dependency injection, but it just seems like so much effort.
For example I have this function:
private var beacons: [AppBeacon] = []
private var serverBeacons:[Beacon] = []
private func addBeacons(serverBeacons: [Beacon]){
for beacon in serverBeacons {
let beacon = AppBeacon(id: beacon.id, uuid: beacon.uuid, building: beacon.building, name: beacon.name)
beacons.append(beacon)
}
}
there's no way I can test whether the beacons array was actually filled up as I wanted to or not for example. The public features of my class are basically a function called startLocating and the result which is the room id and name and I know in black box testing which unit testing imitates (right?) I should not care about the intermediate steps, but honestly, with this much functionality should I just say, doesn't matter? And assume i did populate the beacons with some rssi values of my choice, the actual location algorithm is executed on a node.js server, so I honestly don't know what to test client side?
It's classic MVC and there's no way I can change it architecture until the deadline that I have, so I don't know what's the best way to go from here? Just don't test the functionalities? Make the fields internal instead of private? We do testing of the algorithm itself server side, so testing whether the the room id is the expected room id, is already tested.
I read on another post the following:
"Unit testing by definition is black box testing, which means you don't care about the internals of the unit you test. You are mainly interested to see what's the unit output based on the inputs you give it in the unit test.
Now, by outputs we can assert on several things:
the result of a method
the state of the object after acting on it,
the interaction with the dependencies the object has
In all cases, we are interested only about the public interface, since that's the one that communicates with the rest of the world.
Private stuff don't need to have unit tests simply because any private item is indirectly used by a public one. The trick is to write enough tests that exercise the public members so that the private ones are fully covered.
Also, one important thing to keep in mind is that unit testing should validate the unit specifications, and not it's implementation. Validating implementation details adds a tight coupling between the unit testing code and the tested code, which has a big disadvantage: if the tested implementation detail changes, then it's likely that the unit test will need to be changed also, and this decreases the benefit having unit test for that piece of code."
And from that I essentially understand it as that I should just not unit test this?
If you have a private var that would help you write unit tests, change it to private(set) var so that it can be read (but not changed).
Revealing the innards may bother you. If it does, it's possible that there's another type waiting to be extracted from the view controller.
First, the definition of 'unit-test' you have quoted is quite unusual: All definitions from the literature that I am aware of consider unit-testing a glass-box/white-box testing method. More precisely, unit-testing as such is actually neither black-box or white-box - it is the method used for designing the test cases that makes the difference. But there is no reason not to apply white-box test design techniques for unit-testing. In fact, some white-box test design techniques make only sense when applied for unit-testing. For example, when you investigate on unit-testing, you will encounter a lot of discussions about different code coverage criteria, like, statement coverage, branch coverage, condition coverage, MC/DC - for all of which it is essential to know the implementation details of the code and consider these implementation details during test case design.
But, even taking that into account, it does not change much for your particular case: The variables in your code are still private :-) However, you are approaching the testing problem in a too restrictive way: You try to test the function addBeacons for itself, in total isolation even from the other functions in that component.
To test addBeacons, your test cases should not only contain a call to addBeacons, but also some other function call, the result of which would show you if the call to addBeacons was successfull. For example, if you also have a function to find a beacon by name or position, you would first call addBeacon and, to check that this has succeeded, call one of these function to see if your added beacon will be found. These two calls would be part of the same test case.
I love the way that you can write clean concise code in Dart, but it appears that Dart is one of those languages that it easy to write but hard to test!
For example, given the following fairly simple method, how does one go about unit testing it?
typedef void HandleWebSocket(WebSocket webSocket);
Router createWebSocketRouter(HttpServer server, String context, HandleWebSocket handler) {
var router = new Router(server);
router.serve(context).transform(new WebSocketTransformer()).listen(handler);
return router;
}
You need to somehow replace the new Router() with some sort of factory method that returns a mock. The mock then needs to return a mock when serve is called. That then needs to have a mock transform* method that returns a mock stream.....and at that point most people will give up!
I have managed to write a unit test using the above approach but as it required 80 odd lines and polluted the actual class with a factory method I can hardly say I am happy with it!
Is there a better way of doing this?
I am fairly new to Dependency Injection, and I wrote a great little app that worked exactly like Mark Seemann told me it would and the world was great. I even added some extra complexity to it just to see if I could handle that using DI. And I could, happy days.
Then I took it to a real world application and spent a long time scratching my head. Mark tells me that I am not allowed to use the 'new' keyword to instantiate objects, and I should instead let the IoC do this for me.
However, say that I have a repository and I want it to be able to return me a list of things, thusly:
public interface IThingRepository
{
public IEnumerable<IThing> GetThings();
}
Surely at least one implementation of this interface will have to instantiate some Thing's? And it doesn't seem so bad being allowing ThingRepository to new up some Things as they are related anyway.
I could instead pass round a POCO instead, but at some point I'm going to have to convert the POCO in to a business object, which would require me to new something up.
This situation seems to occur every time I want a number of things which is not knowable in the Composition Root (ie we only find out this information later - for example when querying the database).
Does anyone know what the best practice is in these kinds of situations?
In addition to Steven's answer, I think it is ok for a specific factory to new up it's specific matching-implementation that it was created for.
Update
Also, check this answer, specifically the comments, which say something about new-ing up instances.
Example:
public interface IContext {
T GetById<T>(int id);
}
public interface IContextFactory {
IContext Create();
}
public class EntityContext : DbContext, IContext {
public T GetById<T>(int id) {
var entity = ...; // Retrieve from db
return entity;
}
}
public class EntityContextFactory : IContextFactory {
public IContext Create() {
// I think this is ok, since the factory was specifically created
// to return the matching implementation of IContext.
return new EntityContext();
}
}
Mark tells me that I am not allowed to use the 'new' keyword to instantiate objects
That's not what Mark Seemann tells you, or what he means. You must make the clear separation between services (controlled by your composition root) at one side and primitives, entities, DTOs, view models and messages on the other side. Services are injectables and all other types are newables. You should only prevent using new on service types. It would be silly to prevent newing up strings for instance.
Since in your example the service is a repository, it seems reasonable to assume that the repository returns domain objects. Domain objects are newables and there's no reason not to new them manually.
Thanks for the answers everybody, they led me to the following conclusions.
Mark makes a distinction between stable and unstable dependencies in the book I am reading ( "Dependency injection in .NET"). Stable dependencies (eg Strings) can be created at will. Unstable dependencies should be moved behind a seam / interface.
A dependency is anything that is in a different assembly from the one that we are writing.
An unstable dependency is any of the following
It requires a run time environment to be set up such as a database, web server, maybe even the file system (otherwise it won't be extensible or testable, and it means we couldn't do late binding if we wanted to)
It doesn't exist yet (otherwise we can't do parallel development)
It requires something that isn't installed on all machines (otherwise it can cause test difficulties)
It contains non deterministic behaviour (otherwise impossible to test well)
So this is all well and good.
However, I often hide things behind seams within the same assembly. I find this extremely helpful for testing. For example if I am doing a complex calculation it is impossible to test the entire calculation well in one go. If I split the calculation up into lots of smaller classes and hide these behind seams, then I can easily inject any arbirtary intermediate results into a calculating class.
So, having had a good old think about it, these are my conclusions:
It is always OK to create a stable dependency
You should never create unstable dependencies directly
It can be useful to use seams within an assembly, particularly to break up big classes and make them more easily testable.
And in answer to my original question, it is ok to instatiate a concrete object from a concrete factory.
When I design MVC apps, I typcially try to keep almost all logic (as much as possible) out of my app. I try to abstact this into a service layer which interfaces with my repositories and domain entities.
So, my controller methods end up looking something like this:
public ActionResult Index(int id)
{
return View(Mapper.Map<User, UserModel>(_userService.GetUser(id)));
}
So assuming that I have good coverage testing my services, and my action methods are simple like the above example, is it overkill to unit test these controller methods?
If you do build unit tests for methods that look like this, what value are you getting from your tests?
If you do build unit tests for methods that look like this, what value
are you getting from your tests?
You can have unit tests that assert:
That the GetUser method of the _userService was invoked, passing the same int that was passed to the controller.
That the result returned was a ViewResult, instead of a PartialViewResult or something else.
That the result's model is a UserModel instance, not a User instance (which is what gets returned from the service).
Unit tests are as much a help in refactoring as asserting the correctness of the application. Helps you ensure that the results remain the same even after you change the code.
For example, say you had a change come in that the action should return a PartialView or JsonResult when the request is async/ajax. It wouldn't be much code to change in the controller, but your unit tests would probably fail as soon as you changed the code, because it's likely that you didn't mock the controller's context to indicate whether or not the request is ajax. So this then tells you to expand on your unit tests to maintain the assertions of correctness.
Definitely value added IMO for 3 very simple methods which shouldn't take you longer than a couple of minutes each to write.
I'm working on a new project where I'm actively trying to honor persistence ignorance. As an example, in my service layer I retrieve an entity from my ORM and I call a routine defined on the entity that may or may not make changes to the entity. Then I rely on my ORM to detect whether or not the entity was modified and it makes the necessary inserts/updates/deletes.
When I run the application it works as intended and it's really neat to see this in action. My business logic is very isolated and my service layer is really thin.
Of course, now I'm adding unit tests and I have noticed that i can no longer write unit tests that verify whether or not certain properties were modified. In my previous solution, I determine whether or not a repository call was made with the object in its expected state.
mockRepository.Verify(mr =>
mr.SaveOrUpdate(It.Is<MyEntity>(x =>
x.Id == 123 && x.MyProp == "newvalue")), Times.Once());
Am I approaching persistence ignorance correctly? Is there a better way to unit test the post-operational state of my entities when I don't explicitly call the repository's save method?
If it helps, I'm using ASP.NET MVC 3, WCF, NHibernate, and NUnit/Moq. My unit tests make calls to my controller actions passing instances of my service classes (which are instantiated with mocked repositories).
You are approaching this correctly in that you have an interface representing your repository and passing in a fake in your tests, I prefer to use an in-memory simulator for my repositories instead of using mocks because I find that stub implementations tend to make my tests less brittle than using mock/verify (as per the mocks aren't stubs article linked above). If your repository has Add/Find/Delete methods, my in-memory implementation will forward those to a member list and then save will set a property called SavedList that I can assert on in my tests.
Oddly enough I just stumbled upon a solution and it is really simple.
[Test]
public void Verify_Widget_Description_Is_Updated()
{
// arrange
var widget = new Widget { };
mockWidgetRepo.Setup(mr => mr.GetWidget()).returns(widget);
var viewModel = new WidgetVM { };
viewModel.Description = "New Desc";
// act
var result = (ViewResult)controller.UpdateWidget(viewModel);
// assert
Assert.AreEqual("New Desc", widget.Description);
}
It's not perfect, but I can assume that if widget.Description matches the value I assigned to my view model, then the ORM would save that change unless evict was called.
UPDATE:
Just came up with another alternative solution. I created a ObjectStateAssertionForTests(Object obj) function in my base repository that does nothing. I can call this function in my code and then check it in my unit tests.
mockRepository.Verify(mr =>
mr.ObjectStateAssertionForTests(It.Is<MyEntity>(x =>
x.Id == 123 && x.MyProp == "newvalue")), Times.Once());