Unit testing a method that uses an external dll - c#

I have a project named A that has a class named ClassA.
ClassA has a method named ReadBlock() which creates a CloudBlockBlob object and calls one of its methods.
CloudBlockBlob is a class which is located in Microsoft.WindowsAzure.Storage.Blob namespace which is in Microsoft.WindowsAzure.Storage.dll.
My project A has a unit testing project named A.Tests.
Now, I want to test method ReadBlock(). To test it, I need to mock the CloudBlockBlob object and intercept the calls to its methods, return custom values and verify that the methods were called.
How can I mock an object that is fully created inside a method?
Can I somehow change project A's dll reference and reference it to a mock dll that creates a mock object instead the real one?
Can I override project A's call for classes inside the Microsoft.WindowsAzure.Storage.Blob with an implementation of my own in A.Tests class?
UPDATE:
The question is whether I can do this without modifying project A's code.
Thanks!

Without modifing class A code you won't be able to UT the ReadBlock method using Moq. You'll be able to UT this method using code weaving tools (MsFakes, Typemock Isolator, etc...)
For example(MsFakes):
[TestMethod]
public void TestMethod1()
{
using (ShimsContext.Create())
{
ShimCloudBlockBlob.AllInstances.<the method you want to override> = (<the method arguments>) => {};
}
}
Inside the using scope you'll be able to override any method CloudBlockBlob has, through the property AllInstances.
In the next section I'm going to discuss all the other options you have...
Option 1:
public class A
{
private IBlockBlob _blockBlob;
public A(IBlockBlob blockBlob)
{
_blockBlob = blockBlob;
}
public void ReadBlock()
{
_blockBlob.DoSomething();
}
}
Since you create a new instance each time call ReadBlock(your method's current behavior) you better inject a factory instead of wrapper and DoSomething should be create; Option 2:
public class A
{
private readonly IFactoryBlockBlob _blobFctory;
public A(IFactoryBlockBlob blobFctory)
{
_blobFctory = blobFctory;
}
public void ReadBlock()
{
var blob = _blobFctory.Create();
}
}
However, based on your question and your comments it seems that your class 'has a dependency' instead of 'needs a dependency'.
(Mark Siemens wrote a great book about DI, this chart was taken from his book)
With this new piece of information your method should be something like; Option 3:
public class A
{
public void ReadBlock(ICloudBlob blob)
{
}
}
But you don't want to change the signature of the method:
public class A
{
public void ReadBlock()
{
ReadBlock(new CloudBlockBlob(<the params bla bla...>));
}
internal void ReadBlock(ICloudBlob blob)
{
}
}
Add InternalsVisibleToAttribute, then verify the behavior of the internal method.
By reading between the lines, it feels to me that your class is a kind of "legacy code" meaning that it can do the job, won't change, and verifying its behavior might be a waste of time. In the past I've posted a chart (in this answer) which may help you to decide the way to handle this case.

Its probably best to create a very simple mockable wrapper for CloudBlockBlob to improve your code's testability and inject it using dependency inversion.
Right now you probably have something like:
public class A
{
public void ReadBlock()
{
var blockBlob = new CloudBlockBlob();
blockBlob.DoSomething();
}
}
Instead, inject your wrapper into A so that the dependency on CloudBlockBlob is not known to A:
public class A
{
IBlockBlob _blockBlob
public A(IBlockBlob blockBlob)
{
_blockBlob = blockBlob;
}
public void ReadBlock()
{
_blockBlob.DoSomething();
}
}

Disclaimer, I work in Typemock.
You can do it without modifying project A's code using Isolator.
There is a simple example how it can be done:
public class Foo
{
public void ReadBlock()
{
var block = new CloudBlockBlob(new Uri("http://myUrl/%2E%2E/%2E%2E"));
var name = block.Name;
}
}
[TestMethod, Isolated]
public void TestReadBlock()
{
//Arrange
var fakeBlock = Isolate.Fake.AllInstances<CloudBlockBlob>();
Isolate.WhenCalled(() => fakeBlock.Name).WillReturn("Name");
//Act
var foo = new Foo();
foo.ReadBlock();
//Assert
Isolate.Verify.WasCalledWithAnyArguments(() => fakeBlock.Name);
}
Hope it helps!

Related

How do I unit test a class that relies on HttpContext.GetGlobalResourceObject?

I'm trying to add tests to a webforms project. There's a static method to grab lines from resource files. One of the classes I'm trying to test, relies on grabbing text from the resource file.
public static class MyStaticClass {
public static string getText(String name)
{
String s = HttpContext.GetGlobalResourceObject("MyResources", name).ToString();
return s;
}
}
public class ClassUnderTest
{
// returns: "Hey it's my text"
private string _eg = MyStaticClass.getText("label_in_resources.resx_file")
}
class UnitTests
{
[Test]
public void TestMyClass()
{
ClassUnderTest _cut = new ClassUnderTest();
// errors out because ClassUnderTest utilizes getText
// which requires HttpContext.GetGlobalResourceObject
// ... other stuff
}
}
Note: these are simplistic examples.
The issue is that I get a Test Failed with the message:
Message: System.NullReferenceException : Object reference not set to an instance of an object.
With my sleuthing, I've determined that this is because HttpContext is null during these tests.
I've looked at quite a few SO posts on mocking HttpContext but I don't think that I fully understand what exactly they're doing as they're typically dealing with MVC and not Webforms. Still most of them use HttpContextBase and/or HttpContextWrapper but again, I'm not sure how to implement them.
Also - I'm not directly testing the getText method. I know it works. I'm testing a class that uses it. Will mocking the HttpContext even help in this situation?
I do realize that this is sort of a hybrid of a unit test / integration test, so if this isn't the best way, I'm all ears... or.. eyes rather.
Edit
For now, I modified my getText method to return the key (name) if the result of HttpContext.GetGlobalResourceObject is null. Then I updated my tests to expect the key instead of the value. It's not ideal, but it works and allows me to continue. If there's a better way, please let me know.
public static class MyStaticClass {
public static string getText(String name)
{
String s = HttpContext.GetGlobalResourceObject("MyResources", name);
return s != null ? s.ToString() : name;
}
}
Original answer with Fakes (see below for dealing with removing static)
So there's one caveat that I completely forgot about until I just tried to do this. I am pretty sure Fakes still requires Enterprise version of VS. I don't know if there's a way to get it to work with NUnit, but when you aren't able to change the code sometimes you have to just deal with it.
Here's an example of Shimming your static method. You don't need to worry about HttpContext (yet) since you aren't using it directly. Instead you can Shim your getText(string) method.
Actual Business Project
namespace FakesExample
{
public class MyStaticClass
{
public static string GetText(string name)
{
throw new NullReferenceException();
}
}
}
Your Unit Test Project
using System;
using Microsoft.QualityTools.Testing.Fakes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FakesExampleTests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
using (ShimsContext.Create())
{
FakesExample.Fakes.ShimMyStaticClass.GetTextString = (s) =>
{
return "Go away null reference";
};
Console.WriteLine(FakesExample.MyStaticClass.GetText("foo"));
}
}
}
}
I actually ran this so I know it works. What happens is that even though GetText will always throw a NullReferenceException when called, our Shim of it returns our own custom message.
You may have to make a Visual Studio Test Project.
In your Unit Test project, right-click your reference and say "Add Fakes". It will generate all of the Shims and Stubs for your assembly.
Process of removing the static
The best solution is to actually work towards removing the static. You've already hit one major reason to not use them.
Here's how I would go about removing the static and removing the dependency on HttpContext
public interface IResourceRepository
{
string Get(string name);
}
public class HttpContextResourceRepository : IResourceRepository
{
public string Get(string name)
{
return HttpContext.GetGlobalResourceObject("MyResources", name).ToString();
}
}
public class MyFormerStaticClass
{
IResourceRepository _resourceRepository;
public MyFormerStaticClass(IResourceRepository resourceRepository)
{
_resourceRepository = resourceRepository;
}
public string GetText(string name)
{
return _resourceRepository.Get(name);
}
}
I would then leverage Dependency Injection to handle the creation of my HttpContextResourceRepository and MyStaticClass (which should probably also be interfaced) in the actual business code.
For the unit test, I would mock the implementation
[TestFixture]
public class UnitTest1
{
[Test]
public void TestMethod1()
{
var repoMock = new Mock<IResourceRepository>();
repoMock.Setup(repository => repository.Get("foo")).Returns("My Resource Value");
var formerStatic = new MyFormerStaticClass(repoMock.Object);
Console.WriteLine(formerStatic.GetText("foo"));
}
}
Going this route, you can create any number of IResourceRepository implementations and swap them whenever you want.

Need to create fakes for a class that manipulates the results of interface in microsoft unit testing tool using c#

I need to implement fakes for unit testing one of my methods. Problem is the method I need to test calls a class method and retrieves some system parameters.Scenario is as below:
Class A(){
public void method xx(){
//This needs to be tested.
//This method makes a call to retrieve some informations. The call is like
below:
String culture=Api.GetEnvironmentData().GetCulture();
//This is the problem area.
boolean implmentApi=Api.GetEnvironmentData().DoImplmentApi();
//This is the problem area.
}
}
This GetEnvironmentData method is something like this:
public static EnvironmentData GetEnvironmentData ()
{
return GetDiContainer().Resolve<EnvironmentData >();
}
EnvironmentData class is something like this:
public class EnvironmentData(){
public EnvironmentData(IEnvironmentDataProvider EnvironmentDataProvider){
//
}
}
I can fake the IEnvironmentDataProvider using moq but am not able to figure out how to fake the EnvironmentData class. I need to fake the EnvironmentData class because it manipulated the results of IEnvironmentDataProvider based of various method calls. For example both GetCulture and DoImplmentApi call the getData method of the interface IEnvironmentDataProvider and then cast them accordingly.
Now when I fake the IEnvironmentDataProvider and return some value I am not able to control what to return when GetCulture and when DoImplmentApi is called.
Can some one suggest how to implement the fakes for the above scenario.
You don't need to mock dependencies of EnvironmentData class. I see one problem here: you are using DI container, like Service Locator, which in this scenario behave like antipattern. All dependencies should be injected, e. g.: by constructor or property.
Change your Api class to something like this:
public class Api
{
private readonly EnvironmentData _environmentData;
public Api(EnvironmentData envData)
{
environmentData = envData;
}
public string GetCulture()
{
return _envData.GetCulture();
}
}
Remember that implementation details of Api class should be hidden. You shouldn't expose EnvironmentData in this scenario. Api class should ask for all dependencies which are needed to implement this class and has own interface.
Based on your comments, I think your best shot is to wrap the static class in a facade. Then you can mock the facade.
Something like this:
Class A
{
IEnvironmentDataFacade _environmentDataFacade;
Class A(IEnvironmentDataFacade environmentDataFacade)
{
_environmentDataFacade = environmentDataFacade;
}
public void method xx()
{
//Now you can fake IEnvironmentDataFacade:
String culture= _environmentDataFacade.GetCulture();
//Do the same as above with the method here:
boolean implmentApi=Api.GetEnvironmentData().DoImplmentApi();
//This is the problem area.
}
}
public class EnvironmentDataFacade : IEnvironmentDataFacade
{
public string GetCulture()
{
return Api.GetEnvironmentData().GetCulture();
}
}
public interface IEnvironmentDataFacade
{
string GetCulture();
}

How to mock a function call in the method I am testing - currently using NSubsitute

I am new to trying to mock things in unit tests...
Example Code simplified for posting:
namespace MockInvestigate.Monitor
{
internal interface IAgentRepo
{
Dictionary<string, string> GetAgentAppSettings(string moduleName);
}
public class AgentRepo : IAgentRepo
{
public virtual Dictionary<string, string> GetAgentAppSettings(string moduleName)
{
return new Dictionary<string, string> { { "real", "data" } };
}
}
}
This is the method I want to unit test - but override the call to GetAgentAppSettings
namespace MockInvestigate
{
public class Class1
{
public static bool IsInitialized(string taskName)
{
AgentRepo ar = new AgentRepo();
var arReturn = ar.GetAgentAppSettings(taskName);
return arReturn.ContainsKey("real");
}
}
}
The unit test - trying to mock the call to 'GetAgentAppSettings'
[TestMethod]
public void TestMethod1()
{
var repo = Substitute.ForPartsOf<AgentRepo>();
var appReturn = new Dictionary<string, string> { { "bogus", "bogus2" } };
repo.GetAgentAppSettings("somevalue").ReturnsForAnyArgs(appReturn);
bool retValue = Class1.IsInitialized("somevalue");
Assert.IsFalse(retValue);
}
When my test is run, the real GetAgentAppSettings is called, returning "real", "data" and not the bogus data I want.
I have tried .When(...).DoNotCallBase().
Can my test be modified to work? Does the underlying code need to change to work?
Any help would be appreciated.
After creating the substitute repo, you have to inject it inside Class1.
In your code, however, you are creating the AgentRepo inside the IsInitialized method, thus it's not using the substitute you created in the test method.
You have to inject the substitute by constructor injection, property injection or method injection.
As the name suggests, constructor injection is when you inject the dependency from the constructor. Since the method IsInitialized is static, that's not an option.
Likewise, property injection uses properties to inject the dependencies. You could create a static property, usually you'd stay away from it though.
It'd always use the same instance for every thread, hence you'd have to guarantee that the AgentRepo is thread-safe.
As last resort, you can use the method injection. You'd get the AgentRepo instance as a method argument and let the caller be responsible for creating it.
Since this is a small repro, I can't tell you what's the best way to deal with it. What I do know is that the AgentRepo must be injected into Class1 somehow.

How to type cast interface to a concrete type

I am trying to mock the ManagementObjectSearcher class and have created a IManagementInfo interface, so how can i cast the interface to the ManagementObjectSearcher class?
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info = s as IManagementInfo;
this creates me a null info object
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info =IManagementInfo(s);
this gives me run time error (cannot typecast)
You cannot do that. Do you want to do it so that you can write unit tests? If you are trying to mock a class that you have no control of, then you have to wrap it in another class.
public class MyManagementObjectSearcherWrapper : IManagementInfo
{
public void TheMethodToMock()
{
var searcher = new ManagementObjectSearcher();
// The code you want to mock goes here
}
}
And you run your code like this:
public void YourCode(IManagementInfo info)
{
info.TheMethodToMock();
}
Then YourCode() will take either your wrapper or the mocked object. You create your mock using the IManagementInfo interface.
It looks as if you are trying to wrap a 3rd party/system object in order to aid unit testing.
Say that your starting point is
public class Dependency {
public string Foo() {
return "foo"; // machine, system, time, something else, dependent result
}
public string Bar() {
return "bar";
}
}
public class MySimpleClass {
public string MyFunc() {
return new Dependency().Foo();
}
}
[TestMethod]
public void TestSimple() {
var client = new MySimpleClass();
Assert.AreEqual("foo", client.MyFunc());
}
We are creating the Dependency inside the call because we are considering the creation cost to be less important than holding on to an instance of the Dependency. This will be dependent upon the situation. We could as easily have created a Dependency in the ctor and stored a copy which we invoked each time. Either way, we have no control over the output which makes unit testing messy.
We need to create a proxy for it.
1. Define an interface for the members that we need
Most likely, we do not need to use all of the members of the wrappee so only include in the interface those about which we care.
public interface IDependencyProxy {
string Foo();
}
2. Create a Proxy Class
We then create a proxy class wrapping the dependency and implementing interface. Again, we can create at start or on a call by call basis.
public class DependencyProxy : IDependencyProxy {
public string Foo() {
return new Dependency.Foo();
}
}
3. Define our client code in terms of the interface
We modify our client code slightly to use the IDependencyProxy interface instead of the Dependency. There are a few ways of doing this. I generally use an internal ctor which takes the dependency chained from a public ctor. (Use [InternalsVisibleTo] to allow the unit tests to see it)
public class MyRevisedClass {
private readonly IDependencyProxy dependency;
public MyRevisedClass()
: this( new DependencyProxy()) {}
internal MyRevisedClass(IDependencyProxy dependency) {
this.dependency = dependency;
}
public string MyFunc() {
return dependency.Foo();
}
}
This allows us a default behaviour for the production code (invokes the System object) and allows us to mock out the results for unit testing.
[TestMethod]
public void TestRevisedDefault() {
var client = new MyRevisedClass();
Assert.AreEqual("foo", client.MyFunc());
}
[TestMethod]
public void TestRevisedWithMockedDependency() {
var dep = new Mock<IDependencyProxy>();
dep.Setup(mk => mk.Foo()).Returns("bar");
var client = new MyRevisedClass(dep.Object);
Assert.AreEqual("bar", client.MyFunc());
}

Moq and constructors - testing initialisation behaviour

I'd like to be able to test a class initialises correctly using Moq:
class ClassToTest
{
public ClassToTest()
{
Method1(#"C:\myfile.dat")
}
public virtual void Method1(string filename)
{
// mock this method
File.Create(filename);
}
}
I thought I'd be able to use the CallBase property to create a testable version of the class, then use .Setup() to ensure Method1() does not execute any code.
However, creating the Mock<ClassToTest>() doesn't call the constructor, and if it did it'd be too late to do the Setup()!
If this is impossible, what is the best way round the problem whilst ensuring that the constructor behaves correctly?
EDIT: To make it clearer, I've added a parameter to Method1() to take a filename and added some behaviour. The test I'd like to write would be a working version of the following:
[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
var mockClass = new Mock<ClassToTest>() { CallBase = true };
mockClass.Setup(x => x.Method1(It.IsAny<string>());
mockClass.Verify(x => x.Method1(#"C:\myfile.dat"));
}
Way down inside of Moq.Mock (actually inside the CastleProxyFactory that Moq uses)
mockClass.Object
will call the constructor by way of Activator.CreateInstance()
So your test would look something like
[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
Mock<ClassToTest> mockClass = new Mock<ClassToTest>();
mockClass.Setup(x => x.Method1(It.IsAny<string>());
var o = mockClass.Object;
mockClass.Verify(x => x.Method1(#"C:\myfile.dat"));
}

Categories