some time ago I prepared an idl file to define the interface for plugins of a VB6 application.
Reviewing code I found there is an interface which looks like this:
[
odl,
uuid(<some guid>),
version(1.0),
nonextensible, oleautomation
]
interface IPlugin : IUnknown {
HRESULT DoSomething();
}
This interface is used in some VB6 and C++ components (dlls) to expose the main plugin class, also the exe refers to the typelibrary to keep a reference of plugin classes.
What I would like to do now is to remove odl, version and nonextensible because not required, and then add the object attribute to correctly define a COM interface.
Now that the entire system is in production, can I change attributes on the interface?
Can I do it without compatibility issues?
Thank you
Related
I'm working on a dotnet core project, trying to mock some third party classes in my Xunit.net tests. The class I'm trying to fake is not mockable through constrained frameworks like Moq or NSubstitute. So I need an unconstrained framework to do that.
Say I want to fake DateTime.Now in my .net core test projects.
In .net 4.5 we have MSFakes(Moles), Smocks, etc. None of them support dotnet core framework yet. Shim is not ported to dotnet core yet.
Anyone knows any isolation framework or technique that will achieve my goal for .NET Core at the present time?
You could try a different way: wrap those third party libs with your own interfaces and wrapper classes. Then use a dummy object implementing that interface.
Things become more complicated with static properties like DateTime.Now. But it works similar: define an ITimeProvider interface with a Now property. Add a DateTimeWrapper : ITimeProvider with a public DateTime Now => DateTime.Now;, and - for convenience, but not required - a static class around it, e.g.
static class MyClock
{
static ITimeProvider _Instance;
static void SetInstanceForTesting(ITimeProvider instance)
{ _Instance = instance; }
static DateTime Now => _Instance.Now;
}
Alternatively, you may inject an ITimeProvider instance to the objects needing it.
A somewhat late reply, but for anyone else looking after the same kind of functionality I would recommend the open source git project prig: https://github.com/urasandesu/Prig It can fake static methods (they even have an example of faking and isolating DateTime.Now) and is an alternative to Microsoft Fakes, TypeMock and JustMock (all who cost money or require ultimate editions of visual studio to use).
Pose is an option. It's free full in memory
Https://GitHub.com/tonerdo/pose
I have a business rule visual studio class library (.NET 2.0) project that takes a dependency on Dynamics Crm Web Services - a classic SOAP web reference as opposed to a WCF endpoint. I want to unit test those business rules without having a real crm instance behind it. Adding a web reference doesn't produce an interface that I can fake. It does generate c# in my project that I think I can fake if I can create the interface. I don't think I need to actually navigate HTTP and get into all of the protocol stuff.
I saw Joh Skeet's blog post. Alas I didn't want to write any code and I'm hoping a tool has been written since then that might help. I tried some of his steps but concluded that he is smarter than me and I couldn't make that work.
I am aware of SoapUI, however, I was hoping for pure unit tests that would work in a CI build environment.
Is there a way to do this.
The standard way to mock something which doesn't come with an interface, is to build your own wrapper around it.
the code you want to mock, say the webservice stuff:
class AutoGeneratedStuff
{
public string GeneratedMethodYouUse()
{...}
public string GeneratedMethodYouDontNeed()
{...}
}
you then make an interface which covers only the bits of the code you need:
public interface IWebServiceClient
{
string MethodYouUse();
}
and a concrete wrapper class which implements it, which has a dependency to the generated stuff
class WebServiceClient : IWebServiceClient
{
private AutoGeneratedStuff _stuff;
public WebService(AutogeneratedStuff stuff)
{
_stuff = stuff;
}
public string MethodYouUse()
{
return _stuff.MethodYouUse();
}
}
then, in your code when you would have called the generated class, call your interface instead. In your unit tests, you can mock the interface, either using a mocking framework, or by implementing the interface with another concrete class that has no dependencies to the generated stuff
I'm trying to create a unit test for a code similar to this:
foreach (string domainName in Directory.GetDirectories(server.Path))
{
HandleDomainDirectory(session, server, domainName);
}
The problem is that I'm using the System.IO.Directory class in my code.
How can I create a testing method that won't be dependent on any folder I have on my hard disk.
In other words, How can I fake the response of "Directory.GetDirectories(server.Path)"?
(Please note, I do control the "server" object in my class, therefore i can give any path i want)
Thanks.
Rather than calling Directory.GetDirectories(server.Path) directly, you could create an interface like IDirectoryResolver with a single method that takes a path string and returns the list of directories. The class containing your code above would then need a property or field of type IDirectoryResolver, which can be injected through the constructor or a setter.
For your production code, you would then create a new class that implements the IDirectoryResolver interface. This class could use the Directory.GetDirectories method in its implementation of the interface method.
For unit testing, you could create a MockDirectoryResolver class which implements IDirectoryResolver (or use a mocking library to create a mock instance for the interface). The mock implementation can do whatever you need it to do.
You would inject a wrapper class.
public class DirectoryFetcher
{
public virtual List<string> GetDirectoriesIn(string directory)
{
return Directory.GetDirectories(directory);
}
}
And then inject that:
foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path))
{
// Whatever
}
You can then Mock that guy at the injection point (this example uses Moq, and constructor injection):
Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>();
mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string>
{
"SampleDirectory1",
"SampleDirectory2"
});
MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object);
// Do Test
When communicating with the outside world, such as file system, databases, web services etc. , you should always consider using wrapper classes like the others before me suggested. Testability is one major argument, but an even bigger one is: The out side world changes, and you have no control over it. Folders move, user rights changes, new disk drives appears and old ones are removed. You only want to care about stuff like that in one place. Hence, the wrapper -- let's call it DirectoryResolver like Andy White suggested ealier.
So, wrap your file system calls, extract an interface, and inject that interface where you need to communicate with the file system.
The best solution I've found was to use Moles. The code is very specific, and must do very specific thing. Wrapping it with wrapper class will be redundant. The only reason I needed wrapper class is in order to write tests. Moles allows me to write the tests without any wrapper class :)
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.
I've written some customer class loader that load some classes from a certain directory (that is not in the classpath), say:
class FileSystemClassLoader extends Classloader{
// implementation details
}
I have some directory say /home/mhewedy/classes/ that is not in the classpath, this directory contains some classes that I use the previous classlaoder to load.
how to use this classloader from the my code to load classes "simplicity" without writing : such code:
Thread.currentThread().setContextClassLoader(new FileSystemClassLoader());
// some code here ...
ClassLoader contextCL = Thread.currentThread().getcontextClassLoader();
Update to respond to OP edits:
When the JVM loads a class, it will use the classloader that loaded the "current" class (per JVM spec). So if you're in method Foo.main(), which was loaded with your custom classloader, and you want to create an instance of Bar, also loaded via that classloader, you don't have to do anything special.
However, if your current method is Baz.main(), and it was loaded via the system classpath (specified with -cp on the command line), then you have to explicitly load that class via the classloader. There's no way around this. The "context classloader" is meant for application code, to load resources; the JVM ignores it.
In almost all cases, you're better off constructing a classpath that includes your special classes.