Avoid run part of code when use Unit test - ios

I want that don't execute part of my code when I run the app for Unit testing, the problem is one my functions is save one object in BD and I want avoid this.
api.getUsers(completion:{(objects)
//In this response I save the object in BD
})

I don't think you really want to conditionally execute something at runtime based if you are running unit tests or not. That would be a terrible idea IMHO.
What you probably want in your unit tests is to create a mock object of your api class and then inject the mocked version into the class you are testing.

Does your operating system has environmental values? In React, I solve this with checking process.env.NODE_ENV !='test'

You can set an on-launch argument like isTest to YES in your scheme properties (section Test).
And, in your function use this :
BOOL isTest = [[NSUserDefaults standardUserDefaults] boolForKey:#"isTest"];

Related

Mock initial viewController - code coverage results

I've a problem and I don't know the solution even after several hours of try and error and googling and stackoverflowing.
I have a view controller. I would like to pass per dependency injection an object. This object derives from a protocol. In general it is not a problem to setup a unit test. Also mocking works and the unit tests are running. So where's the problem?
I am testing only one class in my primary target. This class has absolutely nothing to do with view controller. But the code coverage is showing me a decent percent value of covering the view controllers. After a while I found out that when I hit the "test" button the project gets executed as if I push the "run" button. And because of that the view controller gets initialized and created and I have no chance to pass another dependency first, or before the tests getting executed.
So I need a method to distinguish between a test run and a real run, to pass in one case a real object and in the other case the fake object.
And my question is, how to to that? I wonder why nobody have this problem. I mean what gives me the code coverage tool if it shows me that methods are covered even though I haven't tested them.
The one and only class that I am testing:
And these are the coverage results (The bars are just gray because Xcode lost focus during screenshot. Otherwise they are blue.):
So I was expecting to see covered in the results just the class I am testing and not everything else. I know why this problem persists. The view controller has a dependency and this dependency after it gets initialized creates some more classes and so on. What I would like to do is to pass a fake object during unit testing and a real object during a real run. Just like It works in Visual Studio for non ui tests: If the tests are executed the application does NOT start up. The test runner just initialize the subjects under test and that's all. And this is what I want to achieve for iOS unit tests. I guess I've missed sth. very important :(
For all of us who have or will have the same problem. The solution is to specify environment variables for the test run. After that you can check if you are running your unit tests with code like this (assuming you have created an environment variable called "InTestMode" and set the value to "1" during test run:
let dict = NSProcessInfo.processInfo().environment
if let env = dict["InTestMode"] as? String?
{
return env == "1"
}
return false

Understanding Mock Unit Testing

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.

Verify method call with OCMockito

I have these two methods in a ClassA
-(IBAction)onSubmit;
-(void)validateName:(NSString*)name;
#Implementation
- (IBAction)onSubmit {
[self validateName:self.textfield.text];
}
-(void)validateName:(NSString*)name{
// do something
}
My test look like the below:
//given
ClassA *classA = mock([ClassA class]);
classA.textfield.text = #"Foo";
// when
[classA onSubmit];
[verify(classA) validateName:#"Foo"];
But that doesn't work, I keep getting:
Expected 1 matching invocation, but received 0
How can I write a test that verifies that validateName is executed, when onSubmit is being called.
Proper unit tests test internal state and external behavior. Your unit tests are testing whether your code does something, not how it does something. The state verification tells you that your intended results are achieved, while the behavior verification tells you that your collaborating objects correctly interface with your system under test. This allows you to do wonderful things like refactor.
A test of internal state goes like this:
Given an initial state, if the system under test does something, then
the resultant state should be this.
A test of external behavior goes like this:
If the system under test does something, then another unit should do something else.
The first sort of tests are accomplished with standard assertions (assertThat() calls in the case of OCHamcrest). The second sort of tests are (properly) accomplished with verification of test doubles (verify() calls in the case of OCMockito).
It wouldn’t make any sense to mock the system under test. If you find it necessary to test the internal behavior (i.e. the particular methods called by the system under test), then you need to map those behaviors to states. In your case this would mean that ClassA implements a flag such as BOOL nameValidated (preferably with the getter isNameValidated) or a variable such as NSString *validatedName.

how to troubleshoot intermittent junit test failures?

I am dealing with a case where my tests pass or fail based on the order of declaration. This of-course points to not properly isolated tests. But I am stumped about how to go about finding the issue.
The thing is my junit tests derive from a class that is belongs to a testing framework built on junit and has some dependency injection container. The container gets reset for every test by the base class setup and so there are no lingering objects at least in the container since the container itself is new. So I am leaning toward the following scenario.
test1 indirectly causes some classA which sets up classA.somestaticMember to xyz value. test obj does not maintain any references to classA directly- but classA is still loaded by vm with a value xyz when test1 ends.
test2 access classA and trips up on somestaticmember having xyz value.
The problem is a) I dont know if this is indeed the case- how do I go about finding that ? I cannot seem to find a reference to a static var in the code...
b) is there a way to tell junit to dump all its loaded classes and do it afresh for every test method ?
You can declare a method with #Before, like
#Before public void init()
{
// set up stuff
}
and JUnit will run it before each test. You can use that to set up a "fixture" (a known set of fresh objects, data, etc that your tests will work with independently of each other).
There's also an #After, that you can use to do any cleanup required after each test. You don't normally need to do this, as Java will clean up any objects you used, but it could be useful for restoring outside objects (stuff you don't create and control) to a known state.
(Note, though: if you're relying on outside objects in order to do your tests, what you have isn't a unit test anymore. You can't really say whether a failure is due to your code or the outside object, and that's one of the purposes of unit tests.)

Grails withCriteria testing

I'd like to test a "withCriteria" closure and am not sure how to go about it. I see how to mock out the withCriteria call, but not test the code within the closure. When running the test that executes the "withCriteria", I keep getting a MissingMethodException, even though the code runs fine under the normal flow of execution. Any ideas?
Thanks!
Steve
I wouldn't go that route. Instead I'd move the query into the domain class as a static finder method and test it directly in an integration test with real data. Then you can easily mock the helper method when it's called in a controller or service test.
class YourDomainClass {
...
static List<YourDomainClass> findFooBar() {
YourDomainClass.withCriteria {
...
}
}
}
Then in a unit test:
def results = [instance1, instance2, instance3]
YourDomainClass.metaClass.static.findFooBar = { -> results }
This way you test that the query works against the in-memory database in an integration test but it's easy to mock it in unit tests.
Further to Burt's answer, check out named queries as described here:
http://blog.springsource.com/2010/05/24/more-grails-1-3-features/
You can then mock the property/method access in your unit tests as described by Burt.
Since nobody mentioned the option to create a DSL to run other DSLs here's a full disclosure of this method. I use it quite often with very good results.
Groovy/Grails testing DSLs
There's no mock implementation for Hibernate criteria at the present time. You'll need to use integration tests. However, Burt's recommendation of making this a static finder method is a good one for code organization. You should also look at named queries, described at http://www.grails.org/1.2+Release+Notes, for a nice syntax for this.

Resources