Facebook login with androidx - facebook-login

I am trying to implementing facebook login with androidx but I am getting the following problem while adding facebook dependancy.i have tried alot of things but did nit worked
Program type already present: android.support.v4.app.INotificationSideChannel$Stub$Proxy
here is my Gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
//used for dimensions
implementation 'com.intuit.ssp:ssp-android:1.0.6'
implementation 'com.intuit.sdp:sdp-android:1.0.6'
// camera view
implementation 'com.otaliastudios:cameraview:2.0.0-beta05'
dependencies {
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
}
//recyclerview
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0-rc01'
implementation project(path: ':imagecropper')
implementation project(path: ':amazons3library')
implementation 'com.google.firebase:firebase-auth:18.0.0'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.chaos.view:pinview:1.4.3'
implementation 'com.google.android.material:material:1.0.0'
implementation 'de.hdodenhof:circleimageview:3.0.0'
//
// // facebook SDK
implementation 'com.facebook.android:facebook-login:5.1.1'
}
please help :(

Related

QuarkusTest with Mongo and PanacheMock in Kotlin failing on Mokito.when

I am working on a Quarkus project with MongoDB and Kotlin using PanacheMongoEntity.
The Problem:
Mockito.when throws an error when using with PanacheMock.mock
The error:
when() requires an argument which has to be 'a method call on a mock'.
See the error logs (at bottom) for more info.
Question:
Is it even possible to do it this way in Quarkus-Kotlin?
The documentation at https://quarkus.io/guides/mongodb-panache-kotlin does not cover the testing part, it just refers to the java examples.
Code examples
Dependencies (Gradle)
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-arc'
implementation 'io.quarkus:quarkus-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation 'io.quarkus:quarkus-resteasy-jackson'
implementation 'io.quarkus:quarkus-mongodb-panache-kotlin'
implementation 'io.quarkus:quarkus-security-jpa'
// TESTING
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
testImplementation 'io.quarkus:quarkus-panache-mock'
// makes final classes testable remove when mockito core implemented
testImplementation 'org.mockito:mockito-inline'
testImplementation 'io.rest-assured:kotlin-extensions'
}
The entity
#MongoEntity(collection = "anything")
class Anything : PanacheMongoEntity() {
companion object : PanacheMongoCompanion<Anything> {}
lateinit var id: String
lateinit var type: String
}
The test:
#QuarkusTest
class AnythingResourceTest {
#Test
fun testFetchAllAnythings() {
PanacheMock.mock(Anything::class.java)
val anything = Anything()
anything.id = "id"
anything.type = "type"
Mockito.`when`(Anything.Companion.listAll()).thenReturn(listOf(anything))
}
}
The resulting error log
2022-08-23 19:03:11,290 INFO [org.mon.dri.connection] (Test worker) Opened connection [connectionId{localValue:3, serverValue:137}] to localhost:27017
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
at com.asking.AnythingResourceTest.testFetchAllAnythings(AnythingResourceTest.kt:12)
at java.base#17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base#17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base#17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base#17.0.2/java.lang.reflect.Method.invoke(Method.java:568)

Java module dependencies and testImplementation dependencies

I apologise if this is a duplicate - a link to another answer would be great, but I am having difficulty knowing what to search for.
I am building a library (kotlin, but I can jump between kotlin and java terminology quite happily). In this library I want the unit tests to depend upon an external library.
I have added a line to build.gradle.kts
testImplementation("library-group:library-name:0.0.13")
And it all compiles fine, I can publish the library to maven-local, and use it. But when I want to run the tests I get an IllegalAccessException because my module info.java does not specify a dependency upon the library that the tests depend upon.
I know it can be done - the test code depends upon JUnit, but that is not declared in module info. My guess is that there is a fairly simple incantation to add to build.gradle.kts but I do not know what to search for..... any help gratefully received.
Edit1:
The library that I depend upon at test time is modular.
The problem is that when I run the tests that access classes in library-group:library-name these are not present. I get an IllegalAccess exception as the required class is not present. It is as if I need two moduleinfo.java files, one for test and one for production.
/Edit1
Some relevant parts of build.gradle.kts:
plugins {
// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
id("org.jetbrains.kotlin.jvm") version "1.5.31"
// Apply the java-library plugin for API and implementation separation.
`java-library`
`maven-publish`
// https://plugins.gradle.org/plugin/org.jlleitschuh.gradle.ktlint
id("org.jlleitschuh.gradle.ktlint") version "10.1.0"
// https://github.com/java9-modularity/gradle-modules-plugin/blob/master/test-project-kotlin/build.gradle.kts
id("org.javamodularity.moduleplugin") version "1.8.9"
}
dependencies {
// Align versions of all Kotlin components
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
// Use the Kotlin JDK 8 standard library.
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation(kotlin("test"))
// https://logging.apache.org/log4j/kotlin/index.html
// https://github.com/apache/logging-log4j-kotlin
implementation("org.apache.logging.log4j:log4j-api-kotlin:1.0.0")
implementation("org.apache.logging.log4j:log4j-api:2.11.1")
implementation("org.apache.logging.log4j:log4j-core:2.11.1")
testImplementation("library-group:library-name:0.0.13")
}
tasks.test { useJUnitPlatform() }
kotlin { explicitApi = ExplicitApiMode.Strict }
tasks.compileKotlin { kotlinOptions.allWarningsAsErrors = true }

Unit tests for a simple game loop using SDL

Background
This is my first time writing unit tests in C++. I am using Catch2 as a test framework and I have 2 projects set up in my Visual Studio solution: one for my application, and one for the tests.
I have a simple game loop that I want to test. Something like this:
Application.h
#ifndef APPLICATION_H
#define APPLICATION_H
namespace Rival {
class Application {
public:
void start();
};
} // namespace Rival
#endif // APPLICATION_H
Application.cpp
#include "pch.h"
#include "Application.h"
#include <SDL.h>
namespace Rival {
void Application::start() {
Uint32 nextUpdateDue = SDL_GetTicks();
while (!exiting) {
Uint32 frameStartTime = SDL_GetTicks();
if (nextUpdateDue <= frameStartTime) {
// Update the game logic, as many times as necessary to keep it
// in-sync with the refresh rate.
while (nextUpdateDue <= frameStartTime) {
state->update();
nextUpdateDue += TimerUtils::timeStepMs;
}
state->render();
} else {
// Sleep until next frame is due
Uint32 sleepTime = nextUpdateDue - frameStartTime;
SDL_Delay(sleepTime);
}
}
}
} // namespace Rival
Problem
The problem is the #include <SDL.h>.
I want to be able to mock methods from this header, for example SDL_GetTicks().
I don't want to actually include SDL, if I can help it; I want to keep my unit tests lightweight and free from any window creation / rendering code.
How is this normally accomplished?
The answer is to apply the Fundamental Theorem of Software Engineering, which says that you can solve virtually any problem by adding a new layer of abstraction.
Here that means you wrap your SDL calls in a class that you can swap out at test time. Define an interface (abstract base class), then implement one derivative that uses SDL, and implement another (or use a mock) for tests. Only the SDL implementation will know about SDL, so the tests will not even include or link it.
BTW, for a great summary of testing in C++, see this episode of CppCast on designing for test.
In the end I solved this by stubbing the library functions I was using. You can find my commit with the working test implementation here.
This is somewhat similar to #metal's suggestion, but instead of adding a new layer of abstraction I relied on the fact that my test project did not include the library headers, which meant that I was free to provide my own substitutions for use in the tests.
Maybe the documentation I produced in the process will help someone else:
The test project includes all headers defined by Main-Project, but does not include the headers from third-party libraries. This is to help keep the tests lightweight; we do not want to create an OpenGL context every time we run our tests.
This means that we have to provide stub implementations for any third-party definitions that we depend upon. Stub or mock implementations of Main-Project definitions can also be provided for files that depend heavily on third-party libraries (e.g. Texture). Other source files from Main-Project can be directly included in the test project, as required.
To keep the project organised, several filters have been created:
Test Framework: Files required to get the tests to run.
Source Files: Unmodified source files under test, imported directly from Main-Project.
Test Doubles: Test-only implementations of Main-Project headers.
Tests: The tests themselves.
As an aside, the Catch2 framework has been excellent so far, and has added no extra complexity whatsoever.

Mockito cannot mock/spy because final class [duplicate]

I have a final class, something like this:
public final class RainOnTrees{
public void startRain(){
// some code here
}
}
I am using this class in some other class like this:
public class Seasons{
RainOnTrees rain = new RainOnTrees();
public void findSeasonAndRain(){
rain.startRain();
}
}
and in my JUnit test class for Seasons.java I want to mock the RainOnTrees class. How can I do this with Mockito?
Mocking final/static classes/methods is possible with Mockito v2 only.
add this in your gradle file:
testImplementation 'org.mockito:mockito-inline:2.13.0'
This is not possible with Mockito v1, from the Mockito FAQ:
What are the limitations of Mockito
Needs java 1.5+
Cannot mock final classes
...
Mockito 2 now supports final classes and methods!
But for now that's an "incubating" feature. It requires some steps to activate it which are described in What's New in Mockito 2:
Mocking of final classes and methods is an incubating, opt-in feature. It uses a combination of Java agent instrumentation and subclassing in order to enable mockability of these types. As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line:
mock-maker-inline
After you created this file, Mockito will automatically use this new engine and one can do :
final class FinalClass {
final String finalMethod() { return "something"; }
}
FinalClass concrete = new FinalClass();
FinalClass mock = mock(FinalClass.class);
given(mock.finalMethod()).willReturn("not anymore");
assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
In subsequent milestones, the team will bring a programmatic way of using this feature. We will identify and provide support for all unmockable scenarios. Stay tuned and please let us know what you think of this feature!
add this in your build file:
if using gradle: build.gradle
testImplementation 'org.mockito:mockito-inline:2.13.0'
if using maven: pom.xml
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>2.13.0</version>
<scope>test</scope>
</dependency>
this is a configuration to make mockito work with final classes
If you faced the Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)
Add the Byte Buddy dependency to your build.gradle file:
testImplementation 'net.bytebuddy:byte-buddy-agent:1.10.19'
src: https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy
You cannot mock a final class with Mockito, as you can't do it by yourself.
What I do, is to create a non-final class to wrap the final class and use as delegate. An example of this is TwitterFactory class, and this is my mockable class:
public class TwitterFactory {
private final twitter4j.TwitterFactory factory;
public TwitterFactory() {
factory = new twitter4j.TwitterFactory();
}
public Twitter getInstance(User user) {
return factory.getInstance(accessToken(user));
}
private AccessToken accessToken(User user) {
return new AccessToken(user.getAccessToken(), user.getAccessTokenSecret());
}
public Twitter getInstance() {
return factory.getInstance();
}
}
The disadvantage is that there is a lot of boilerplate code; the advantage is that you can add some methods that may relate to your application business (like the getInstance that is taking a user instead of an accessToken, in the above case).
In your case I would create a non-final RainOnTrees class that delegate to the final class. Or, if you can make it non-final, it would be better.
In Mockito 3 and more I have the same problem and fixed it as from this link
Mock Final Classes and Methods with Mockito
as follow
Before Mockito can be used for mocking final classes and methods, it needs to be > configured.
We need to add a text file to the project's src/test/resources/mockito-extensions directory named org.mockito.plugins.MockMaker and add a single line of text:
mock-maker-inline
Mockito checks the extensions directory for configuration files when it is loaded. This file enables the mocking of final methods and classes.
Use Powermock. This link shows, how to do it: https://github.com/jayway/powermock/wiki/MockFinal
Just to follow up. Please add this line to your gradle file:
testCompile group: 'org.mockito', name: 'mockito-inline', version: '2.8.9'
I have tried various version of mockito-core and mockito-all. Neither of them work.
I had the same problem. Since the class I was trying to mock was a simple class, I simply created an instance of it and returned that.
I guess you made it final because you want to prevent other classes from extending RainOnTrees. As Effective Java suggests (item 15), there's another way to keep a class close for extension without making it final:
Remove the final keyword;
Make its constructor private. No class will be able to extend it because it won't be able to call the super constructor;
Create a static factory method to instantiate your class.
// No more final keyword here.
public class RainOnTrees {
public static RainOnTrees newInstance() {
return new RainOnTrees();
}
private RainOnTrees() {
// Private constructor.
}
public void startRain() {
// some code here
}
}
By using this strategy, you'll be able to use Mockito and keep your class closed for extension with little boilerplate code.
Another workaround, which may apply in some cases, is to create an interface that is implemented by that final class, change the code to use the interface instead of the concrete class and then mock the interface. This lets you separate the contract (interface) from the implementation (final class). Of course, if what you want is really to bind to the final class, this will not apply.
Time saver for people who are facing the same issue (Mockito + Final Class) on Android + Kotlin. As in Kotlin classes are final by default. I found a solution in one of Google Android samples with Architecture component. Solution picked from here : https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample
Create following annotations :
/**
* This annotation allows us to open some classes for mocking purposes while they are final in
* release builds.
*/
#Target(AnnotationTarget.ANNOTATION_CLASS)
annotation class OpenClass
/**
* Annotate a class with [OpenForTesting] if you want it to be extendable in debug builds.
*/
#OpenClass
#Target(AnnotationTarget.CLASS)
annotation class OpenForTesting
Modify your gradle file. Take example from here : https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/build.gradle
apply plugin: 'kotlin-allopen'
allOpen {
// allows mocking for classes w/o directly opening them for release builds
annotation 'com.android.example.github.testing.OpenClass'
}
Now you can annotate any class to make it open for testing :
#OpenForTesting
class RepoRepository
Actually there is one way, which I use for spying. It would work for you only if two preconditions are satisfied:
You use some kind of DI to inject an instance of final class
Final class implements an interface
Please recall Item 16 from Effective Java. You may create a wrapper (not final) and forward all call to the instance of final class:
public final class RainOnTrees implement IRainOnTrees {
#Override public void startRain() { // some code here }
}
public class RainOnTreesWrapper implement IRainOnTrees {
private IRainOnTrees delegate;
public RainOnTreesWrapper(IRainOnTrees delegate) {this.delegate = delegate;}
#Override public void startRain() { delegate.startRain(); }
}
Now not only can you mock your final class but also spy on it:
public class Seasons{
RainOnTrees rain;
public Seasons(IRainOnTrees rain) { this.rain = rain; };
public void findSeasonAndRain(){
rain.startRain();
}
}
IRainOnTrees rain = spy(new RainOnTreesWrapper(new RainOnTrees()) // or mock(IRainOnTrees.class)
doNothing().when(rain).startRain();
new Seasons(rain).findSeasonAndRain();
Give this a try:
Mockito.mock(SomeMockableType.class,AdditionalAnswers.delegatesTo(someInstanceThatIsNotMockableOrSpyable));
It worked for me. "SomeMockableType.class" is the parent class of what you want to mock or spy, and someInstanceThatIsNotMockableOrSpyable is the actual class that you want to mock or spy.
For more details have a look here
This can be done if you are using Mockito2, with the new incubating feature which supports mocking of final classes & methods.
Key points to note:
1. Create a simple file with the name “org.mockito.plugins.MockMaker” and place it in a folder named “mockito-extensions”. This folder should be made available on the classpath.
2. The content of the file created above should be a single line as given below:
mock-maker-inline
The above two steps are required in order to activate the mockito extension mechanism and use this opt-in feature.
Sample classes are as follows:-
FinalClass.java
public final class FinalClass {
public final String hello(){
System.out.println("Final class says Hello!!!");
return "0";
}
}
Foo.java
public class Foo {
public String executeFinal(FinalClass finalClass){
return finalClass.hello();
}
}
FooTest.java
public class FooTest {
#Test
public void testFinalClass(){
// Instantiate the class under test.
Foo foo = new Foo();
// Instantiate the external dependency
FinalClass realFinalClass = new FinalClass();
// Create mock object for the final class.
FinalClass mockedFinalClass = mock(FinalClass.class);
// Provide stub for mocked object.
when(mockedFinalClass.hello()).thenReturn("1");
// assert
assertEquals("0", foo.executeFinal(realFinalClass));
assertEquals("1", foo.executeFinal(mockedFinalClass));
}
}
Hope it helps.
Complete article present here mocking-the-unmockable.
Yes same problem here, we cannot mock a final class with Mockito. To be accurate, Mockito cannot mock/spy following:
final classes
anonymous classes
primitive types
But using a wrapper class seems to me a big price to pay, so get PowerMockito instead.
I think you need think more in principle. Instead you final class use his interface and mock interface instead.
For this:
public class RainOnTrees{
fun startRain():Observable<Boolean>{
// some code here
}
}
add
interface iRainOnTrees{
public void startRain():Observable<Boolean>
}
and mock you interface:
#Before
fun setUp() {
rainService= Mockito.mock(iRainOnTrees::class.java)
`when`(rainService.startRain()).thenReturn(
just(true).delay(3, TimeUnit.SECONDS)
)
}
Please look at JMockit. It has extensive documentation with a lot of examples. Here you have an example solution of your problem (to simplify I've added constructor to Seasons to inject mocked RainOnTrees instance):
package jmockitexample;
import mockit.Mocked;
import mockit.Verifications;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(JMockit.class)
public class SeasonsTest {
#Test
public void shouldStartRain(#Mocked final RainOnTrees rain) {
Seasons seasons = new Seasons(rain);
seasons.findSeasonAndRain();
new Verifications() {{
rain.startRain();
}};
}
public final class RainOnTrees {
public void startRain() {
// some code here
}
}
public class Seasons {
private final RainOnTrees rain;
public Seasons(RainOnTrees rain) {
this.rain = rain;
}
public void findSeasonAndRain() {
rain.startRain();
}
}
}
Solutions provided by RC and Luigi R. Viggiano together is possibly the best idea.
Although Mockito cannot, by design, mock final classes, the delegation approach is possible. This has its advantages:
You are not forced to change your class to non-final if that is what your API intends in the first place (final classes have their benefits).
You are testing the possibility of a decoration around your API.
In your test case, you deliberately forward the calls to the system under test. Hence, by design, your decoration does not do anything.
Hence you test can also demonstrate that the user can only decorate the API instead of extending it.
On a more subjective note:
I prefer keeping the frameworks to a minimum, which is why JUnit and Mockito are usually sufficient for me. In fact, restricting this way sometimes forces me to refactor for good as well.
If you trying to run unit-test under the test folder, the top solution is fine. Just follow it adding an extension.
But if you want to run it with android related class like context or activity which is under androidtest folder, the answer is for you.
Add these dependencies for run mockito successfully :
testImplementation 'org.mockito:mockito-core:2.24.5'
testImplementation "org.mockito:mockito-inline:2.24.5"
Mocking final classes is not supported for mockito-android as per this GitHub issue. You should use Mockk instead for this.
For both unit test and ui test, you can use Mockk with no problem.
If you need to use Mockito in an instrumented test in Android (i. e. running in an Android device), you cannot use mockito-inline. There is a special mockito-android version which doesn't solve the "final class" problem either. The only solution which seems to work is the Dexmaker library. The only limitation is that it works only in Android P (Android 9, API 28) and higher. It can be imported as follows:
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.1"
Beware that there is also a "dexmaker-mockito" version which doesn't work for final classes either. Make sure you import "dexmaker-mockito-inline".
As others have stated, this won't work out of the box with Mockito. I would suggest using reflection to set the specific fields on the object that is being used by the code under test. If you find yourself doing this a lot, you can wrap this functionality in a library.
As an aside, if you are the one marking classes final, stop doing that. I ran across this question because I am working with an API where everything was marked final to prevent my legitimate need for extension (mocking), and I wish that the developer had not assumed that I would never need to extend the class.
For us, it was because we excluded mockito-inline from koin-test. One gradle module actually needed this and for reason only failed on release builds (debug builds in the IDE worked) :-P
For final class add below to mock and call static or non static.
1- add this in class level
#SuppressStatucInitializationFor(value ={class name with package})
2- PowerMockito.mockStatic(classname.class) will mock class
3- then use your when statement to return mock object when calling method of this class.
Enjoy
I was able to overcome this message:
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class org.slf4j.impl.Log4jLoggerAdapter
Mockito cannot mock/spy because :
final or anonymous class
from this: log = spy(log);
By using this instead:
log = mock(Logger.class);
Then it works.
I guess that "default" logger adapter is an instance of a final class so I couldn't "spy" it, but I could mock the whole thing. Go figure...
This may mean that you could substitute it for some other "non final" instance if you have that handy, as well. Or a simplified version, etc. FWIW...
I am writing the steps I followed after various unsuccessful attempts to mock final/private classes and their methods in Java 11, which finally worked for me.
Create a file named org.mockito.plugins.MockMaker inside
your test/resources/mockito-extensions folder. Please create
mockito-extensions folder if not present already.
Add a single line mock-maker-inline as the content of the above org.mockito.plugins.MockMaker file
Add
#RunWith(PowerMockRunner.class)
#PowerMockIgnore({"javax.management.*", "jdk.internal.reflect.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"})
#PrepareForTest(Utility.class)
annotations at the class level.
Setup process in the test class
#Before
public void setup () {
MockitoAnnotations.initMocks(this);
Mockito.mockStatic(ClassToBeMocked.class);
}
Use Mockito.when(..).thenReturn(..) for assertions
In case of multiple test cases, add the below code
#After
public void after() {
Mockito.framework().clearInlineMocks();
}
The mockito version which I am using: 3.9.0
Java version: 11
Didn't try final, but for private, using reflection remove the modifier worked ! have checked further, it doesn't work for final.

What is the correct way to extend an existing ActiveX/COM component?

I am updating an MFC application that contains a custom ActiveX control. As a part of the update I have had cause to add new methods to the ActiveX control and so it now has a different interface to the old version. The changes had no impact on the original methods and so older clients can still use the new component.
I've got everything working but I know that what I have done is smelly! What is the correct way of updating a COM/ActiveX interface.
This component was built using MFC and Googling does not provide much help beyond basic 'Create an ActiveX control with MFC' type tutorials. I can find loads of stuff about ATL but I don't want to port the component over.
I have had various suggestions from colleagues such as change the guids and inherit the interface but nothing definitive.
So generally what is considered best practise for updating COM interfaces?
And if you happen to know how this is specifically done in an MFC environment that would be really helpful too.
I've tried creating a second interface (see below) as suggested by MSalters but I'm not sure that I've gone about it correctly. I've created a new interface and a new coclass in the odl file. This results in two separate wrapper classes being generated by MFC in the client Application, one derived from CWnd for coclass Test and one derived from COleDispatchDriver for coclass Test2 - I would have expected two similar wrapper classes....
library TestLib
{
importlib(STDOLE_TLB);
// This is the original interface.......
[ uuid(D2F8E5A8-8A95-463C-814F-B3CF84286223)]
dispinterface _DTest
{
properties:
methods:
[id(1)] short TestMethod();
};
// Class information for CTestCtrl
[ uuid(1DBD2333-2073-4FB6-89AC-E4B200ADED48), control ]
coclass Test
{
[default] dispinterface _DTest;
};
// This is the new interface.
[ uuid(D2F8E5A8-8A95-463C-814F-B3CF84286224)]
dispinterface _DTest2
{
properties:
methods:
[id(1)] short TestMethod();
[id(2)] short TestMethod2();
};
// Class information for CTestCtrl2
[ uuid(1DBD2333-2073-4FB6-89AC-E4B200ADED49), control ]
coclass Test2
{
[default] dispinterface _DTest2;
};
};
Depends.
If you do have customers that are compiling their own code (C++ or C# or VB) against your controls's type library, .h file, or .idl file, you likely need to change the COM guids.
Here are the cases where you don't have to change the COM guids:
No 3rd party developers are consuming your code. No one would be broken if you changed the interface.
It's an ActiveX control hosted in a webbrowser and accessed through Javascript.
All the software depending on your COM DLL ships together with the updated version of your control.
It's "internal". Anyone dependent can quickly recompile if needed.
If any one of the above is true, then you don't have to change COM guids. Just add the new methods to the existing interface declaration. Recompile all dependent software with the change.
Here are the cases where you should be careful.
Someone else has already compiled (C++, C#, or VB) and shipped software against your existing interface - and they can't immediately upgrade when you ship. New methods should be declared on a new COM interface. The existing coclass declaration gets amended to support this interface as well.
You are removing methods, changing behavior, or otherwise making a breaking change to shipping software. Change your guid on the CoClass such that it can possibly co-exist side by side with those dependent on the old version. Rename the DLL as well such that it doesn't necessarily overwrite the old one on upgrade.
In your above example, I don't think you need to declare a new coclass - just a new interface. And your new interface doesn't need to implement the methods of the first. Just make mark both interfaces on the coclass.
dispinterface _DTest
{
properties:
methods:
[id(1)] short TestMethod();
};
// This is the new interface.
[ uuid(D2F8E5A8-8A95-463C-814F-B3CF84286224)]
dispinterface _DTest2
{
properties:
methods:
[id(2)] short TestMethod2();
};
// Class information for CTestCtrl
[ uuid(1DBD2333-2073-4FB6-89AC-E4B200ADED48), control ]
coclass Test
{
[default] dispinterface _DTest;
dispinterface _DTest2;
}
};
You can always add interfaces. The new control can simply implement the old and new interfaces at the same time. Inheritance is an easy C++ technique to recycle large parts of the old interface and implementation.