A .NET Unit Test without a parameterless constructor, to facilitate dependency injection - unit-testing

I'm trying to have the unit tests not rely on calling container.Resolve<T>() for their dependencies.
I'm currently using AutoFac 2.2.4, and tried xUnit.NET and NUnit, but both have this issue:
No parameterless constructor defined for this object
How do I get past this issue? Is it a particular unit testing framework that will support this, or just how said framework is configured?
Should I not be doing this? Or can I set up the test class to work with the constructor that has it's only dependency?
Here's some of the code:
public class ProductTests : BaseTest
{
readonly private IProductRepository _repo;
public ProductTests(IProductRepository r)
{
_repo = r;
}
//working unit tests here with default constructor
}
Did I choose to initialise the container wrongly in the base class constructor?
public abstract class BaseTest
{
protected BaseTest()
{
var builder = new ContainerBuilder();
builder.RegisterType<ProductRepository>().As<IProductRepository>();
builder.Build();
}
}

The initial problem is indeed due to how the testing frameworks are designed. They all require a parameterless constructor in order to instantiate test instances. And rightfully so. With these frameworks, the constructor is not to be relied on for test initialization. That is the purpose of the SetUp method. All in all, the test classes themselves are not suited for injection.
And IMO, this becomes a non-issue when you develop your tests to not depend on the container. After all, each test class should focus on one "system under test" (SUT). Why not have the setup method instantiate that system directly and provide each dependency (usually in the form of fakes)? By doing it this way you have effectively removed another unnecessary dependency from your tests, namely the IoC framework.
On a side note: the only time I involve the IoC framework in my tests is in my "container tests". These tests focus on verifying that certain services can be resolved from the container after the container have been initialized with application or assembly modules.

I just allow my tests to have a dependency on Autofac, although I encapsulate it. All of my TestFixtures inherit from Fixture, which is defined as such:
public class Fixture
{
private static readonly IContainer MainContainer = Ioc.Build();
private readonly TestLifetime _testLifetime = new TestLifetime(MainContainer);
[SetUp]
public void SetUp()
{
_testLifetime.SetUp();
}
[TearDown]
public void TearDown()
{
_testLifetime.TearDown();
}
protected TService Resolve<TService>()
{
return _testLifetime.Resolve<TService>();
}
protected void Override(Action<ContainerBuilder> configurationAction)
{
_testLifetime.Override(configurationAction);
}
}
public class TestLifetime
{
private readonly IContainer _mainContainer;
private bool _canOverride;
private ILifetimeScope _testScope;
public TestLifetime(IContainer mainContainer)
{
_mainContainer = mainContainer;
}
public void SetUp()
{
_testScope = _mainContainer.BeginLifetimeScope();
_canOverride = true;
}
public void TearDown()
{
_testScope.Dispose();
_testScope = null;
}
public TService Resolve<TService>()
{
_canOverride = false;
return _testScope.Resolve<TService>();
}
public void Override(Action<ContainerBuilder> configurationAction)
{
_testScope.Dispose();
if (!_canOverride)
throw new InvalidOperationException("Override can only be called once per test and must be before any calls to Resolve.");
_canOverride = false;
_testScope = _mainContainer.BeginLifetimeScope(configurationAction);
}
}

Related

Unit testing a started Service which has a few fields injected into it?

I am a Dagger newbie.
TL;DR:
If an Android Service has any fields injected into it using Dagger, then in order to actually perform the injection, I need to have an instance of that Service.
In Robolectric tests, this corresponds to MyService service = Robolectric.buildService(MyService.class).get(). And then, objectGraph.inject(service);
However, rest of the code that actually starts MyService still uses context.startService(context, MyService.class);.
Question: What is the idiomatic way in Dagger to address this mismatch?
Let's say I have a Service as follows:
public class MyService {
#Inject Parser parser;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String data = intent.getStringExtra("data_to_be_parsed");
parser.parse(data);
}
}
Elsewhere in my code, I have an ApiClient class that does this:
public class ApiClient{
public static void parseInBackground(Context context, String data){
//This service does not have its fields injected
context.startService(new Intent(context, MyService.class).putExtra("data_to_be_parsed", data));
}
}
That parseInBackground method will be called from an Activity in response to user interaction.
Now, I'm following TDD and hence, I haven't yet written the Application Module for this. Here's the test module:
#Module(injects = MyService.class)
public class TestModule {
#Provides #Singleton Parser provideParser(){
return new MockParser();
}
}
And finally, the test case:
#RunWith(Robolectric.class)
public class ApiTest {
#Test
public void parseInBackground_ParsesCorrectly(){
//This service has its fields injected
MyService service = Robolectric.buildService(MyService.class).get();
ObjectGraph.create(new TestModule()).inject(service);
ApiClient.parseInBackground(Robolectric.application, "<user><name>droid</name></user>");
//Asserts here
}
}
As you can see, in the test, I retrieve an instance of the service and then inject the MockParser into it. However, the ApiClient class directly starts the service using an Intent. I don't have a chance to perform the injection.
I am aware that I can have MyService perform an injection on itself:
public void onCreate(){
ObjectGraph.create(new TestModule()).inject(this);
}
But then, I am hardcoding the TestModule here.
Is there an existing idiom in Dagger to set up dependencies for such situations?
It's the wrong way to hardcode your modules either in tests or in services. Better approach is to perform creation via your custom Application object which in turn will hold singleton ObjectGraph object. For example:
// in MyService class
#Override public void onCreate() {
super.onCreate();
MyApp.from(context).inject(this);
}
// in MyApp class
public static MyApp from(Context context) {
return (MyApp) context.getApplicationContext();
}
//...
private ObjectGraph objectGraph;
#Override public void onCreate() {
// Perform Injection
objectGraph = ObjectGraph.create(getModules());
objectGraph.inject(this);
}
public void inject(Object object) {
objectGraph.inject(object);
}
protected Object[] getModules() {
// return concrete modules based on build type or any other conditions.
}
Alternatively, you can refactor last method out into separate class and make different implementations for different flavors or build types. Also you may want to set overrides=true in your TestModule's annotation.

Replacing PowerMock's #PrepareForTest programmatically?

I am using PowerMock to mock static methods in junit tests, typically done as follows:
#RunWith(PowerMockRunner.class)
#PrepareForTest({Foo.class,Bar.class})
public class SomeUnitTest {
#Before
public void setUpTest() {
setUpFoo();
setUpBar();
}
private void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
#Test
public void someTestCase() {
...
}
}
This works fine, but I'm finding that specifying the #PrepareForTest annotation is preventing me from making my testing API flexible.
What I'd like to do is something like the following:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
#RunWith(PowerMockRunner.class)
public class SomeUnitTest {
#Before
public void setUpTest() {
MockLibraryOne.setUpLibraryOne();
}
#Test
public void someTestCase() {
...
}
}
Here my unit test has a dependency on LibraryOne, but it does not know which classes LibraryOne depends on, so it does not know which classes to add to the #PrepareForTest annotation.
I could make SomeUnitTest extend MockLibraryOne and add the #PrepareForTest annotation to the MockLibraryOne class, but I will have dependencies on more than just MockLibraryOne in other unit tests, so inheritance is not a general solution.
Is there some way of programmatically preparing a class for testing under PowerMock, instead of using the #PrepareForTest annotation? For example, something like the following:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
prepareForTest(Foo.class);
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
prepareForTest(Bar.class);
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
I guess it would be nice if PowerMockRunner processed the #PrepareForTest annotation a little differently: for each specified class, it should not only add that class (and its hierarchy) to the list of classes to prepare for mocking, but then examine that class to see if it has any #PrepareForTest annotations as well:
#RunWith(PowerMockRunner.class)
#PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
...
}
#PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
...
}
}
So in this the #PrepareForTest annotation on SomeUnitTest would find MockLibraryOne, and the #PrepareForTest annotation there would drag in Foo.class and Bar.class as well.
So perhaps writing my own test runner to replace PowerMockRunner may be a solution.
Or perhaps there's a simpler solution, using PowerMockAgent class, for example?
edit: Mock Policies may be one solution: https://code.google.com/p/powermock/wiki/MockPolicies
edit: Mock Policies works with PowerMockRunner but not (it seems) with PowerMockRule (which I sometimes require due to class loader issues).
What you try to achieve will not work.
The problem is that powermock must rewrite the client class's code to intercept the static invocation and it can't do this after the class is loaded. Thus it can only prepare a class for test before it is loaded.
Let's assume you want to mock the System.currentTimeMillis invocation in the following simple class.
class SystemClock {
public long getTime() {
return System.currentTimeMillis();
}
}
Powermock will not change the code of java.lang.System.currentTimeMillis, because it can't. Instead it changes the SystemClock's byte code so that it does not invoke System.currentTimeMillis anymore. Instead it invokes some other object that belong to powermock.
This is how powermock get's full control over the return value and allows you to write a test like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ SystemClock.class })
public class PowerMockitoTest {
#Test
public void systemTimeMillis() {
SystemClock systemClock = new SystemClock();
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.currentTimeMillis()).thenReturn(12345L);
long time = systemClock.getTime();
assertEquals(12345L, time);
}
}
You can see that powermock has rewritten the client class in the stacktrace of your debugger. Set a breakpoint at SystemClock.getTime and step into the invoked method.
As you can see SystemClock invokes a MockGateway.
If you take a look at the variables on the stack of the MockGateway invocation, you can see how the original System.currentTimeMillis method is handled.
Perhaps you're looking for a mock policy?
Could you help this (taken from documentation)?
You can also prepare whole packages for test by using wildcards:
#PrepareForTest(fullyQualifiedNames="com.mypackage.*")
So you can add the whole library to your prepare...
Why do you even want to mock static methods? Why not wrap those static methods in a class that you can mock with mockito?
class FooWraper {
void someMethod() {
Foo.someStaticMethod()
}
}
and then you can create a mock of your FooWraper. No need to use Powermock at all...

Castle Windsor: unit test component lifecycle

I would like to write a non-regression test to validate that transient components are well released. Some are created by a direct injection in ctor, other by typed factories.
I thought that I could do this way:
// Given
var rootComponent = container.Resolve<IRootComponent>();
var c1 = rootComponent.C1;
var c2 = c1.C2;
etc.
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c2));
// When
c1.Close();
// Then
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c2));
HasTrack() always returns false, although if I look at the container in debug mode, I can see my components well tracked. Why is that? Do you have any suggestion for such a test?
Thx for your help
The reason that your components are not tracked is that the component and it's dependencies have no decomissioning requirements. In this case there is no reason for windsor to track them.
When using windsor in general you should only resolve on your container once to obtain your top level component. All other component are either injected or created by a factory. There is no need to worry about the live time of injected components. The container will handle it for you.
For transient components that you create with a factory you should be aware that they will never live (be tracked) longer then the factory it self. So if you don't mind that your components live at long as your factory there is no need to release them (using a destroy method on a factory).
For component that I want to make sure that I release them, I generally I create unit test for which I stub out the factory. That way it is easy to test that destroy is called.
I think with the approach that you are taking you are not just testing your code but also the container. IMHO windsor is already well tested, and test should focus on your own code.
Good luck,
Marwijn.
Two years too late, but here's a test.
public class DependsOnSomethingDisposable
{
private readonly SomethingDisposable _disposable;
public Boolean SomethingDisposableIsDisposed { get { return _disposable.Disposed; } }
public DependsOnSomethingDisposable(SomethingDisposable disposable)
{
_disposable = disposable;
}
}
public class SomethingDisposable : IDisposable
{
public Boolean Disposed { get; private set; }
public void Dispose()
{
Disposed = true;
}
}
[TestClass]
public class WindsorLifestyleTests
{
private IWindsorContainer _container;
[TestInitialize]
public void Setup()
{
_container = new WindsorContainer();
}
[TestCleanup]
public void Cleanup()
{
_container.Dispose();
}
[TestMethod]
public void TransientDependencyIsDisposed()
{
_container.Register(
Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
Component.For<SomethingDisposable>().LifestyleTransient()
);
var resolved = _container.Resolve<DependsOnSomethingDisposable>();
_container.Release(resolved);
Assert.IsTrue(resolved.SomethingDisposableIsDisposed);
}
[TestMethod]
public void NonTransientDependencyIsNotDisposed()
{
_container.Register(
Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
Component.For<SomethingDisposable>().LifestyleSingleton()
);
var resolved = _container.Resolve<DependsOnSomethingDisposable>();
_container.Release(resolved);
Assert.IsFalse(resolved.SomethingDisposableIsDisposed);
}
}

How to mock HttpClientCertificate?

I am trying to unit test an action filter I wrote. I want to mock the HttpClientCertificate but when I use MOQ I get exception. HttpClientCertificate doesnt have a public default constructor.
code:
//Stub HttpClientCertificate </br>
var certMock = new Mock<HttpClientCertificate>();
HttpClientCertificate clientCertificate = certMock.Object;
requestMock.Setup(b => b.ClientCertificate).Returns(clientCertificate);
certMock.Setup(b => b.Certificate).Returns(new Byte[] { });
This is the most awkward case of creating unit testable systems in .NET. I invariable end up adding a layer of abstraction over the component that I can't mock. Normally this is required for classes with inaccessible constructors (like this case), non-virtual methods or extension methods.
Here is the pattern I use (which I think is Adapter pattern) and is similar to what MVC team has done with all the RequestBase/ResponseBase classes to make them unit testable.
//Here is the original HttpClientCertificate class
//Not actual class, rather generated from metadata in Visual Studio
public class HttpClientCertificate : NameValueCollection {
public byte[] BinaryIssuer { get; }
public int CertEncoding { get; }
//other methods
//...
}
public class HttpClientCertificateBase {
private HttpClientCertificate m_cert;
public HttpClientCertificateBase(HttpClientCertificate cert) {
m_cert = cert;
}
public virtual byte[] BinaryIssuer { get{return m_cert.BinaryIssuer;} }
public virtual int CertEncoding { get{return m_cert.CertEncoding;} }
//other methods
//...
}
public class TestClass {
[TestMethod]
public void Test() {
//we can pass null as constructor argument, since the mocked class will never use it and mock methods will be called instead
var certMock = new Mock<HttpClientCertificate>(null);
certMock.Setup(cert=>cert.BinaryIssuer).Returns(new byte[1]);
}
}
In your code that uses HttpClientCertificate you instead use HttpClientCertificateBase, which you can instantiate like this - new HttpClientCertificateBase(httpClientCertificateInstance). This way you are creating a test surface for you to plug in mock objects.
The issue is that you need to specify constructor parameters when creating the mock of the HttpClientCertificate.
var certMock = new Mock<HttpClientCertificate>(ctorArgument);
The bad news is that the ctor for HttpClientCertificate is internal and takes in an HttpContext, so it probably won't work.
Unless you want to write more code to make the class "Testable" I suggest you use Typemock Isolator, Unless specified otherwise it looks for the first c'tor available - public, internal or private and fake (mocks) it's parameters so you won't have to.
Creating the fake object is as simple as:
var fakeHttpClientCertificate = Isolate.Fake.Instance<HttpClientCertificate>();
Another alternative is to use the free Microsoft Moles framework. It will allow you to replace any .NET method with your own delegate. Check out the link as it gives an example that is pretty easy to understand. I think you'll find it much nicer than adding layers of indirection to get HttpClientCertificate into a testable state.

Unit testing with singletons

I have prepared some automatic tests with the Visual Studio Team Edition testing framework. I want one of the tests to connect to the database following the normal way it is done in the program:
string r_providerName = ConfigurationManager.ConnectionStrings["main_db"].ProviderName;
But I am receiving an exception in this line. I suppose this is happening because the ConfigurationManager is a singleton. How can you work around the singleton problem with unit tests?
Thanks for the replies. All of them have been very instructive.
Have a look at the Google Testing blog:
Using dependency injection to avoid singletons
Singletons are Pathological Liars
Root Cause of Singletons
Where have all the Singletons Gone?
Clean Code Talks - Global State and Singletons
Dependency Injection.
And also:
Once Is Not Enough
Performant Singletons
Finally, Misko Hevery wrote a guide on his blog: Writing Testable Code.
You can use constructor dependency injection. Example:
public class SingletonDependedClass
{
private string _ProviderName;
public SingletonDependedClass()
: this(ConfigurationManager.ConnectionStrings["main_db"].ProviderName)
{
}
public SingletonDependedClass(string providerName)
{
_ProviderName = providerName;
}
}
That allows you to pass connection string directly to object during testing.
Also if you use Visual Studio Team Edition testing framework you can make constructor with parameter private and test the class through the accessor.
Actually I solve that kind of problems with mocking. Example:
You have a class which depends on singleton:
public class Singleton
{
public virtual string SomeProperty { get; set; }
private static Singleton _Instance;
public static Singleton Insatnce
{
get
{
if (_Instance == null)
{
_Instance = new Singleton();
}
return _Instance;
}
}
protected Singleton()
{
}
}
public class SingletonDependedClass
{
public void SomeMethod()
{
...
string str = Singleton.Insatnce.SomeProperty;
...
}
}
First of all SingletonDependedClass needs to be refactored to take Singleton instance as constructor parameter:
public class SingletonDependedClass
{
private Singleton _SingletonInstance;
public SingletonDependedClass()
: this(Singleton.Insatnce)
{
}
private SingletonDependedClass(Singleton singletonInstance)
{
_SingletonInstance = singletonInstance;
}
public void SomeMethod()
{
string str = _SingletonInstance.SomeProperty;
}
}
Test of SingletonDependedClass (Moq mocking library is used):
[TestMethod()]
public void SomeMethodTest()
{
var singletonMock = new Mock<Singleton>();
singletonMock.Setup(s => s.SomeProperty).Returns("some test data");
var target = new SingletonDependedClass_Accessor(singletonMock.Object);
...
}
Example from Book: Working Effectively with Legacy Code
Also given same answer here:
https://stackoverflow.com/a/28613595/929902
To run code containing singletons in a test harness, we have to relax the singleton property. Here’s how we do it. The first step is to add a new static method to the singleton class. The method allows us to replace the static instance in the singleton. We’ll call it
setTestingInstance.
public class PermitRepository
{
private static PermitRepository instance = null;
private PermitRepository() {}
public static void setTestingInstance(PermitRepository newInstance)
{
instance = newInstance;
}
public static PermitRepository getInstance()
{
if (instance == null) {
instance = new PermitRepository();
}
return instance;
}
public Permit findAssociatedPermit(PermitNotice notice) {
...
}
...
}
Now that we have that setter, we can create a testing instance of a
PermitRepository and set it. We’d like to write code like this in our test setup:
public void setUp() {
PermitRepository repository = PermitRepository.getInstance();
...
// add permits to the repository here
...
PermitRepository.setTestingInstance(repository);
}
You are facing a more general problem here. If misused, Singletons hinder testabiliy.
I have done a detailed analysis of this problem in the context of a decoupled design. I'll try to summarize my points:
If your Singleton carries a significant global state, don’t use Singleton. This includes persistent storage such as Databases, Files etc.
In cases, where dependency on a Singleton Object is not obvious by the classes name, the dependency should be injected. The need to inject Singleton Instances into classes proves a wrong usage of the pattern (see point 1).
A Singleton’s life-cycle is assumed to be the same as the application’s. Most Singleton implementations are using a lazy-load mechanism to instantiate themselves. This is trivial and their life-cycle is unlikely to change, or else you shouldn’t use Singleton.