I am trying to find a way to mock a class without passing the mock version of it explicitly as a parameter via Providers. I just started to use Geolocator and I want to mock a couple of its functions, such as getCurrentPosition.
So far, I've passed the singletons via Providers so that I can mock them when I test the app. However Geolocator is a static class and when I try to provide it with a type, then it says:
The return type 'Type' isn't a 'Geolocator', as required by the closure's context.
The code looks like this:
Provider<Geolocator>(create: (context) => Geolocator)
The cleanest solution seems to be able to inject/provide that class without having to use Provider. However, then I can't pass the MockGeolocator either. So, what should I do?
Related
I have built a file manager(basically reads/writes) class I am trying to unit test. The file format basically belongs to a third party for which I have third party function calls in the constructor. I call all third party calls through wrapper methods
My question is this: Before starting to unit test any method in the class I am trying to instantiate the constructor which looks something like this:
Filemanager::Filemanager{
if(wrapperfoo()){
file->open() //for writing
}
initialise();
}
Now I have a mock class MockManager to mock Filemanager. When I am trying to instantiate MockManager,
I need to mock wrapperoo to return true. However, since the manager itself is not instantiated yet, the EXPECT_CALL fails. Since the EXPECT_CALL has to be placed before the new MockManager()
MockManager *mgr;
EXPECT_CALL(*mgr, wrapperfoo()).Return(true) // Crashes here.. Obviously!!
mgr = new MockManager();
How can I handle this case?
I see no chance for this to work, you are forced to build yourself a workaround. You already gave the explanation yourself.
In principle, mocking isn't designed for what you want to achieve, it is designed for testing components in their behavior to an API or interface, where you mock the interface (API) for the component and not vice versa (https://www.youtube.com/watch?v=dLB2aDasVTg&list=PL_dsdStdDXbo-zApdWB5XiF2aWpsqzV55&index=4, very good explanation). In this example you wouldn't use mocking for internal calls (from the contructor), rather in the test case of another component that requests to get the return type from wrapperfoo().
Is there any way to test a function call via GoogleTest for c++ without creating mock object, e.g. we have the following production code:
if (a)
method(x);
I would like to test whether the method will be called in the case a is True and a is False. I would like to construct a test that does exactly the same what Google Test's EXPECT_CALL does, but EXPECT_CALL works only with the mock object's method. In my case I would prefer not to use a mock (there is no need to create any object).
As state here,
It's possible to use Google Mock to mock a free function (i.e. a C-style function or a static method). You just need to rewrite your code to use an interface (abstract class).
Their "It's possible" is misleading, as you have to rewrite code to use class (abstract, or provided by template), and so no longer use free functions.
If you are trying to fake a free function, you may want to look into the Fake Function Framework (fff). It allows you to replace free functions with fake implementations that can be used in a similar way to GoogleMock.
It works seamlessly with GoogleMock and GoogleTest.
I am using Mockito for unit testing. And there are many matchers like anyString(), anyBoolean() in Mockito. But suppose if I have a custom enum like
Enum LoginType.java
//LoginType.java
public enum LoginType {
FACEBOOK,
EMAIL,
GOOGLE
}
In one of the method arguments I need to pass an instance of LoginType. How do I pass the argument without explicitly passing LoginType.FACEBOOK or LoginType.GOOGLE. Something like anyString(). Any hint in that direction will be useful.
For any behavior, just calling Matchers.any() may be good enough on Java 8. That's when parameter type inference came out.
You might also choose Matchers.any(LoginType.class), which has pure any() behavior in Mockito 1.x but will provide type checking in Mockito 2.0 and beyond. In either case, passing in the class literal will help Java get the type information you need for inference.
For related problems:
If you have a generic type, the class literal isn`t enough either; you need to specify it as an explicit method parameter:
Matchers.<YourContainer<YourType>>any();
...or extract to a static helper method, which you need to do instead of a constant or local variable because Mockito matchers work via side effects:
public static LoginType anyLoginType() {
return Matchers.any();
}
Finally, for future readers who might be here to implement custom matching logic, look for Matchers.argThat or MockitoHamcrest.argThat to adapt a Hamcrest-style Matcher object into a Mockito method call.
I have below code, just putting one scenario here.
class A{
public JSONObject m1(type1,type2,type3){
callmethod2(type3);
}
public Map callmethod2(type3){
//some jobs
return myMap;
}
}
#Test
assertequals(JSONObjectTest,m1(type1,type2,type3))
In my test, I am creating a mock with dummy data and passing them to actual function type1,type2,type3 Now there is callmethod2(type3) as a dependency so i do not want to execute that method. so in my test case i written
when(mockA.callmethod2(any(type3.class))).thenReturn(mockMap);
But i can see my callmethod2 is getting execute, how can i solve this and set some expected result for that method in my test case, so it will not execute.
Your code scenario at the time I am writing this is a little incomplete, but I will try to read between the lines. I assume you are somewhere creating a mock instance of class A. I am also assuming you are using that mocked instance to invoke the instance method "m1".
If either of these things are not true, then you will have problems. If you do not create a mock instance, then the "when(...)" clause will not function properly, and in fact while you are invoking the "when" clause you will also actually be invoking the real (i.e., unmocked) instance of A.m1(). The same will be true if you properly mock A but then don't use the mocked instance in the "when" clause, or if you don't use the mocked version in your execute/assert statement(s).
But the bigger problem is that if you actually ARE properly creating and using a mock of A, then even the default mocked functionality of method "m1" becomes empty -- do nothing. It would never get executed. The only way to do what you seem to be proposing is to use what Mockito calls "partial mocking", using a Spy. You instantiate a real instance of A, then wrap it in a Spy to make a "Spied"-instance of A. Now the Spied instance of A inherits all of the default implementations of methods, and you can mock out specific methods if you like. You then must use the spied instance in both yur "whe(...)" clauses as well as your execute/assert statements.
But even that endeavor is questionable. You should try to test classes as a whole rather than mocking out partial behavior. In general (practically a rule),you should either mock nor spy the class under test. If you see a need to do so then there is probably a coherency problem with your class, and it is pointing to design issues or a misunderstanding of good testing practices.
I use ninject extensively with the factory extension. I also use moq to help with testing and in some cases (particularly complicated view models in my MVVM WPF application) I use the ninject mocking kernel to make it easier to automatically create mocks for resources required by the class under test.
In my regular product code, the ninject factory extension makes it easy to just declare an interface for the factory that looks something like this:
public interface IMyViewModelFactory
{
MyViewModel CreateMyViewModel(int recordNum);
}
and the factory extension will automatically supply an implementation which maps the creation method onto a constructor for the class while resolving any other dependencies that are constructor parameters from ninject. So If my class has a constructor that looks like this:
public MyViewModel(ILogger logger, int recordNum)
{
_logger = logger;
_recordNum = recordNum;
}
then the factory extension will create a factory method implementation that gets the ILogger from the ninject kernel and pass through my explicit parameter.
This all works great for the regular product code, but as near as I can tell I can't get this kind of thing to work in my unit tests when I'm using the mocking kernel.
Normally with the mocking kernel I set it up in the initialization method for my test class, bind a small number of interfaces to concrete classes that I want to test and then let the mocking kernel automatically supply mocks for everything else. These mocks can then be configured as needed for a particular test, and everything works great except for the factory methods. I find myself manually implementing factory methods in setup statements for my mock that look something like this:
Kernel.GetMock<IMyViewModelFactory>()
.Setup(f => f.CreateMyViewModel(It.IsAny<ILogger>(), It.IsAny<int>()))
.Returns((ILogger logger, int recordNum) =>
new MyViewModel(Kernel.Get<ILogger>, recordNum);
That way if my test needs to interact with the factory (or more likely some class I'm testing needs to use the factory to create some sub-view model) then it can actually create the instance and dependencies come from the mocking kernel so they can be setup to mock as needed.
Most of the time I love ninject and these extensions, but this is one place where the unit test setup becomes really tedious. I probably wouldn't even mind except for the fact that I'm so spoiled by how easy the factory extension makes it in my product code, and I can't figure out how to get the same benefit in my tests. Of course the above example is contrived, and sadly in many of my view models the number of dependencies and real parameters is large (and the number of view models where I have to setup this kind of thing is large), so the tedium becomes a bigger deal.
I'm hoping someone can tell me that I'm just missing something obvious and that there's a simple way to set this up.
Thanks,
Danny