mockk kotlin rest api callback - unit-testing

I have read it here. It is close to my problem and I need more guidance on this part.
Given,
class Journey{
fun start(){
Service.getInstance().getProductInfo(activity,object: Service.Callback<Product>{
override fun onSuccess(data: Product) {
showProductInfo(activity, data, customer)
}
override fun onError(e: Throwable) {
showError(e)
}
})
}
}
and I want to mock Service.getProductInfo and perform happy path and unhappy path handling, how do I do it with mockk?
Additional question, is there a way to exclude certain function like start above in jacoco? Sometimes some functions has not much meaning for unit test and excluding it in jacoco makes much more sense.
UPDATE:
I learnt from Gradle website that it does not currently support method exclusion.
Callback interface is below
interface Callback<T>{
fun onSuccess(data: T)
fun onError(e: Throwable)
}
I'm using retrofit for Service.

First, you don't want to exclude your code from code coverage check, because it is your own code and it has to be tested.
For the main problem. In this particular (because mainly I would not use this design at all) case I would go with the way of having ability to mock getInstance method first, so it would return any mock you want to use in your tests. First thing that come to mind is using PowerMockito (or similar mocking frameworks).
PowerMockito allows you to mock static method (see https://github.com/powermock/powermock/wiki/mockstatic) or, which is a bit worse in my mind, but is totally up to you) mock construction of object inside factory method with https://github.com/powermock/powermock/wiki/MockConstructor
My least favorite approach (if you somehow cannot use PowerMock in your code) to do so (as far as I understand it is static method of Service class) can be found here: https://hackernoon.com/mocking-static-method-in-kotlin-614df89482ae
It is pretty simple but you will need to rewrite you code to use it. But if can rewrite your code, it is better to redesign it to make it more testable.
Edit: just realized that you needed to do it with mockk. I'm not really experienced with it, but AFAIK it has almost same fucntionality with staticMockk. You can see this question to check it: Mock static java methods using Mockk

Related

How to best test a service that who's effects get over-written by a stubbed out dependency

First off, my example is in php but this is not a php question, just a question on testing best practices
So I have this function that I would like to test
public function createNewTodo(CreateTodoQuery $query): TodoResponseObject
{
$new_todo = TodoFactory::createNew($query->getUserId(), $query->getTitle())
->withDescription($query->getDescription());
$new_todo = $this->todo_repository->save($new_todo);
return TodoResponseObject::fromDomain($new_todo);
}
In order to test this function, I will need to stub out my dependency (todo_repository). I want to have one test that asserts that what I get back is an instance of a TodoResponseObject. Simple enough
Now the challenging bit: I want to assert that the todo object that gets created with the parameters set in the query. Since I'm going to be stubbing out the todo_repository, I can't actually do that, as my test will just assert on the values of what I configured my stub to return. I could do something like an assertCalledWith type deal, but then at that point I'm going into the anti-pattern of testing that is "testing implementation, not functionality".
So how best could I get around this, and what would be the best way to test this?
See Sandi Metz, Magic Tricks of Testing
If you want to test that your code sent the right message to the factory, then the usual answer is to use a test double (a mock, or a spy) that tracks the messages sent to it so that you can verify them later.
This might require changing the design of your code so that you can more easily substitute one factory implementation for another (for instance, by wrapping a decorator around the "real" factory method).
Another possibility is to split the factory invocation into a separate method, and test that method's handling of the parameters
public function createTodo(CreateTodoQuery $query) {
return TodoFactory::createNew($query->getUserId(), $query->getTitle())
->withDescription($query->getDescription());
}
Changing the design of your implementation so that it better fits with your testing is normal in tdd.

Behavior of doReturn-when and when-thenReturn with mocked vs spied object

When using a spied object as test subject, If we don't want to call nested methods inside the method we are testing, Which of these (doReturn-when or when-thenReturn) can be used to mock those nested methods?
Is there a way to avoid getting invoked the real methods inside the method we are going to test?
In fact doesn't matter if you use doReturn-when or when-thenReturn method for this specific case, because considering a #Spy you will always call the real method.
You can avoid entering other methods by mocking them, but if you are using just Mockito it will be a problem (it doesn't have this approach, but PowerMock does). Particularly I disagree with this approach, because we are being too intrusive in our tests and private flow is a part of the whole flow, but you can do something like this:
SomeService mock = spy(SomeService.class);
doReturn(1).when(mock, "getNumber", ArgumentMatchers.anyInt());
For more details, you can verify PowerMock's official documentation. Also, is nice to know some basic unit testing concepts (stubs, mocks and so on).

How to Unit Test Existing Code that Relies on HttpWebRequest and HttpWebResponse?

I have seen the following questions already:
"Is it possible to mock out a .NET HttpWebResponse?"
"Mocking WebResponse's from a WebRequest"
These do not help me because I need:
To test existing code which uses WebRequest/WebResponse directly, with no interfaces
The existing code depends on HttpWebRequest / HttpWebResponse, so I can't use my own derived WebRequest and WebResponse classes.
I know about WebRequest.RegisterPrefix, and have a successful unit test which proves that it works (once you get the prefix right). But that test simply tests WebRequest and WebResponse.
I tried the following, but it gives a compile error (not a warning):
public class MockWebRequest : HttpWebRequest
{
public MockWebRequest()
// : base(new SerializationInfo(typeof (HttpWebRequest), new FormatterConverter()),
// new StreamingContext())
{
}
}
With the two lines commented-out, I get a compile error:
error CS0619: 'System.Net.HttpWebRequest.HttpWebRequest()' is obsolete: 'This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.'
When I uncomment those lines, I get a 618 warning, but the code crashes at runtime:
System.Runtime.Serialization.SerializationException: Member '_HttpRequestHeaders' was not found.
at System.Runtime.Serialization.SerializationInfo.GetElement(String name, Type& foundType)
at System.Runtime.Serialization.SerializationInfo.GetValue(String name, Type type)
at System.Net.HttpWebRequest..ctor(SerializationInfo serializationInfo, StreamingContext streamingContext)
at UnitTests.MockWebRequest..ctor(String responseJson)
at UnitTests.MockWebRequestCreator.Create(Uri uri)
at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)
at System.Net.WebRequest.Create(Uri requestUri)
at code under test
I'm at a loss about how to proceed with this (other than the default, which is to just punt on these unit tests and wish the code had been implemented with testing in mind).
I could probably get "down and dirty" and do something nasty with ISerializable, or something like that, but this brings up the third requirement:
3. The code must be maintainable, and must not be too much more complex than the code being tested!
OBTW, I can't use TypeMock for this, and in fact there's a bit of a time limit. The project is almost done, so a new, purchased mocking framework is out of the question.
I just ran into the same problem. Frankly, the way Microsoft has set this up doesn't make much sense - in WebRequest.Create they have an abstract factory, but they neither provide interfaces for HttpWebRequest and HttpWebResponse that we can implement, nor do they provide a protected constructor that we can use to inherit from these classes.
The solution I have come up with requires some minor changes to the main program, but it works. Basically, I am doing what Microsoft should have done.
Create interfaces IHttpWebRequest and IHttpWebResponse
Create mock classes which implement the interfaces
Create wrappers for HttpWebRequest and HttpWebResponse which implement the interfaces
Replace calls to WebRequest.Create with my own factory method that returns the wrappers or the mocks, as needed
Depending on how your code is structured, the above may be relatively trivial to implement, or it may require making changes throughout your project. In my case, we have all of our HTTP requests going through a common service, so it hasn't been too bad.
Anyway, probably too late for your project, but maybe this will help someone else down the road.
I generally prefer to use a mocking framework like MOQ when mocking asp.net singletons like httpcontext.
There are other frameworks out there for mocking, but I find MOQ to be very flexible and intuitive
https://github.com/Moq/moq4/wiki/Quickstart
You can do something similar to this
http://www.syntaxsuccess.com/viewarticle/how-to-mock-httpcontext
Another approach is to abstract the call to httpcontext through a virtual method:
Similar to this technique:
http://unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html

tdd - should I mock here or use real implementation

I'm writing program arguments parser, just to get better in TDD, and I stuck with the following problem. Say I have my parser defined as follows:
class ArgumentsParser {
public ArgumentsParser(ArgumentsConfiguration configuration) {
this.configuration = configuration;
}
public void parse(String[] programArguments) {
// all the stuff for parsing
}
}
and I imagine to have ArgumentsConfiguration implementation like:
class ArgumentsConfiguration {
private Map<String, Class> map = new HashMap<String, Class>();
public void addArgument(String argName, Class valueClass) {
map.add(argName, valueClass);
}
// get configured arguments methods etc.
}
This is my current stage. For now in test I use:
#Test
public void shouldResultWithOneAvailableArgument() {
ArgumentsConfiguration config = prepareSampleConfiguration();
config.addArgument("mode", Integer.class);
ArgumentsParser parser = new ArgumentsParser(configuration);
parser.parse();
// ....
}
My question is if such way is correct? I mean, is it ok to use real ArgumentsConfiguration in tests? Or should I mock it out? Default (current) implementation is quite simple (just wrapped Map), but I imagine it can be more complicated like fetching configuration from kind of datasource. Then it'd be natural to mock such "expensive" behaviour. But what is preferred way here?
EDIT:
Maybe more clearly: should I mock ArgumentsConfiguration even without writing any implementation (just define its public methods), use mock for testing and deal with real implementation(s) later, or should I use the simplest one in tests, and let them cover this implementation indirectly. But if so, what about testing another Configuration implementation provided later?
Then it'd be natural to mock such "expensive" behaviour.
That's not the point. You're not mocking complex classes.
You're mocking to isolate classes completely.
Complete isolation assures that the tests demonstrate that classes follow their interface and don't have hidden implementation quirks.
Also, complete isolation makes debugging a failed test much, much easier. It's either the test, the class under test or the mocked objects. Ideally, the test and mocks are so simple they don't need any debugging, leaving just the class under test.
The correct answer is that you should mock anything that you're not trying to test directly (e.g.: any dependencies that the object under test has that do not pertain directly to the specific test case).
In this case, because your ArgumentsConfiguration is so simple, I'd recommend using the real implementation until your requirements demand something more complicated. There doesn't seem to be any logic in your ArgumentsConfiguration class, so it's safe to use the real object. If the time comes where the configuration is more complicated, then an approach you should probably take would be not to create a configuration that talks to some data source, but instead generate the ArgumentsConfiguration object from that datasource. Then you could have a test that makes sure it generates the configuration properly from the datasource and you don't need unnecessary abstractions.

Unit testing factory methods which have a concrete class as a return type

So I have a factory class and I'm trying to work out what the unit tests should do. From this question I could verify that the interface returned is of a particular concrete type that I would expect.
What should I check for if the factory is returning concrete types (because there is no need - at the moment - for interfaces to be used)? Currently I'm doing something like the following:
[Test]
public void CreateSomeClassWithDependencies()
{
// m_factory is instantiated in the SetUp method
var someClass = m_factory.CreateSomeClassWithDependencies();
Assert.IsNotNull(someClass);
}
The problem with this is that the Assert.IsNotNull seems somewhat redundant.
Also, my factory method might be setting up the dependencies of that particular class like so:
public SomeClass CreateSomeClassWithDependencies()
{
return new SomeClass(CreateADependency(), CreateAnotherDependency(),
CreateAThirdDependency());
}
And I want to make sure that my factory method sets up all these dependencies correctly. Is there no other way to do this then to make those dependencies public/internal properties which I then check for in the unit test? (I'm not a big fan of modifying the test subjects to suit the testing)
Edit: In response to Robert Harvey's question, I'm using NUnit as my unit testing framework (but I wouldn't have thought that it would make too much of a difference)
Often, there's nothing wrong with creating public properties that can be used for state-based testing. Yes: It's code you created to enable a test scenario, but does it hurt your API? Is it conceivable that other clients would find the same property useful later on?
There's a fine line between test-specific code and Test-Driven Design. We shouldn't introduce code that has no other potential than to satisfy a testing requirement, but it's quite alright to introduce new code that follow generally accepted design principles. We let the testing drive our design - that's why we call it TDD :)
Adding one or more properties to a class to give the user a better possibility of inspecting that class is, in my opinion, often a reasonable thing to do, so I don't think you should dismiss introducing such properties.
Apart from that, I second nader's answer :)
If the factory is returning concrete types, and you're guaranteeing that your factory always returns a concrete type, and not null, then no, there isn't too much value in the test. It does allows you to make sure, over time that this expectation isn't violated, and things like exceptions aren't thrown.
This style of test simply makes sure that, as you make changes in the future, your factory behaviour won't change without you knowing.
If your language supports it, for your dependencies, you can use reflection. This isn't always the easiest to maintain, and couples your tests very tightly to your implementation. You have to decide if that's acceptable. This approach tends to be very brittle.
But you really seem to be trying to separate which classes are constructed, from how the constructors are called. You might just be better off with using a DI framework to get that kind of flexibility.
By new-ing up all your types as you need them, you don't give yourself many seams (a seam is a place where you can alter behaviour in your program without editing in that place) to work with.
With the example as you give it though, you could derive a class from the factory. Then override / mock CreateADependency(), CreateAnotherDependency() and CreateAThirdDependency(). Now when you call CreateSomeClassWithDependencies(), you are able to sense whether or not the correct dependencies were created.
Note: the definition of "seam" comes from Michael Feather's book, "Working Effectively with Legacy Code". It contains examples of many techniques to add testability to untested code. You may find it very useful.
What we do is create the dependancies with factories, and we use a dependancy injection framework to substitute mock factories for the real ones when the test is run. Then we set up the appropriate expectations on those mock factories.
You can always check stuff with reflection. There is no need to expose something just for unit tests. I find it quite rare that I need to reach in with reflection and it may be a sign of bad design.
Looking at your sample code, yes the Assert not null seems redundant, depending on the way you designed your factory, some will return null objects from the factory as opposed to exceptioning out.
As I understand it you want to test that the dependencies are built correctly and passed to the new instance?
If I was not able to use a framework like google guice, I would probably do it something like this (here using JMock and Hamcrest):
#Test
public void CreateSomeClassWithDependencies()
{
dependencyFactory = context.mock(DependencyFactory.class);
classAFactory = context.mock(ClassAFactory.class);
myDependency0 = context.mock(MyDependency0.class);
myDependency1 = context.mock(MyDependency1.class);
myDependency2 = context.mock(MyDependency2.class);
myClassA = context.mock(ClassA.class);
context.checking(new Expectations(){{
oneOf(dependencyFactory).createDependency0(); will(returnValue(myDependency0));
oneOf(dependencyFactory).createDependency1(); will(returnValue(myDependency1));
oneOf(dependencyFactory).createDependency2(); will(returnValue(myDependency2));
oneOf(classAFactory).createClassA(myDependency0, myDependency1, myDependency2);
will(returnValue(myClassA));
}});
builder = new ClassABuilder(dependencyFactory, classAFactory);
assertThat(builder.make(), equalTo(myClassA));
}
(if you cannot mock ClassA you can assign a non-mock version to myClassA using new)