Suppose I have the following classes from a third-party library:
public class ThirdPartyType { ... }
public class ThirdPartyFunction
{
public ThirdPartyType DoSomething() { ... }
}
The implementation details are not important, and they are actually outside of my control for this third-party library.
Suppose I write an adapter class for ThirdPartyFunction:
public class Adapter
{
private readonly ThirdPartyFunction f;
public Adapter()
{
f = new ThirdPartyFunction();
}
public string DoSomething()
{
var result = f.DoSomething();
// Convert to a type that my clients can understand
return Convert(result);
}
private string Convert(ThirdPartyType value)
{
// Complex conversion from ThirdPartyType to string
// (how do I test this private method?)
...
}
}
How can I test that my implementation of Convert(ThirdPartyType) is correct? It's only needed by the Adapter class, which is why it's a private method.
I would recommend extracting the code to a seprate class and then testing that class. Although it is only used by this Adapter it shouldn't be the responsibility of the adapter to do the conversion as well (in keeping with the Single Responsibility Principle).
By extracting it out it gives you the ability to test the converter in isolation from the third party code.
If the converter does not require any state you could also make it a static class and then reference it directly in your adapter without the need for registering it with dependency injection.
If you think about it, the adapter doesn't need testing (as it is just a wrapper) but the converter does - so extracting it to another class makes sense to allow it to be tested, even if it does mean another class in the code.
In addition, extracting the converter to a separate class means that if the ThirdPartyType or the format of your string changes then you can make the changes without affecting the Adapter implementation.
If you change your Adapter class to allow the ThirdPartyFunction f to be passed to it, then you can use a mock version of it in your test class. this will allow you to test the Convert function.
I'm not sure of the exact syntax as I am not familiar with the language, but I will give it a try:
public class Adapter
{
private readonly ThirdPartyFunction f;
// pass the function to the constructor when creating the adapter
public Adapter(ThirdPartyFunction inputF)
{
f = inputF;
}
public string DoSomething()
{
var result = f.DoSomething();
// Convert to a type that my clients can understand
return Convert(result);
}
private string Convert(ThirdPartyType value)
{
// Complex conversion from ThirdPartyType to string
// (how do I test this private method?)
...
}
}
In your real implementation, when you create the new Adapter, you can pass it a new ThirdPartyFunction.
In your test implementation, you can pass it a Mocked version of that ThirdPartyFunction which returns a fixed value for testing. Maybe like:
class MockThirdPartyFunction extends ThirdPartyFunction
{
private ThirdPartyType testData;
public MockThirdPartyFunction(ThirdPartyType data)
{
testData = data;
}
override public ThirdPartyType DoSomething()
{
// return a fixed third party type passed in on mock creation
return testData
}
}
You create the test adapter with the mocked value, where you can set the specific ThirdPartyType you want to test. Then in your test when you call DoSomething on the Adapter, you are controlling the input to your Convert function and can see the output and compare accordingly to expected results.
Related
I am trying to unit test code that uses an API, so I am trying to decouple.
I have created an interface for the "Application" class inside the API, which is sealed.
I then created a class that uses the interface which has one method that returns an "Application" type object.
Here is where I am having trouble, in my unit test I try to create an "Application" object to verify if the return value is correct. However the "Application" class does not have any constructors, nothing public or private(I checked with reflection). The object is created by calling static Application.Connect(AnotherTypeFromAPI arg), which returns an Application object.
How do I return a fake object that I cannot create?
appMock.Connect(arg).Returns("How do I return an Application object here?"));
Or am I going about this the wrong way in regards to unit testing code that relies on an API? The entire API relies on the "Application" type so if I cannot fake it, I am not sure yet how I can stub or mock the other methods I need.
I am using C#, NUnit, NSUbstitute.
This problem can be solved but you're using the wrong pattern. Instead of exposing an instance of the Application via a new interface, you need to create an interface that fully replaces the concrete dependency.
What you have
If I understand your question correctly, you have a sealed Application class that has some methods your program needs to be able to call, and it has no public constructor, only a static factory method. Here is a simple example for discussion, with only one method, SomeMethod().
public sealed class Application
{
//private ctor prevents anyone from using new to create this
private Application()
{
}
//Here's the method we want to mock
public void SomeMethod(string input)
{
//Implementation that needs to be stubbed or mocked away for testing purposes
}
//Static factory method
static public Application GetInstance()
{
return new Application();
}
}
What you tried
What you did might look like this:
interface IApplication
{
Application Application { get; }
}
class ApplicationWrapper : IApplication
{
protected readonly Application _application;
public ApplicationWrapper()
{
_application = Application.GetInstance();
}
public Application Application
{
get { return _application; }
}
}
So that in your main code, you do this:
var a = new ApplicationWrapper();
a.Application.SomeMethod("Real argument");
That approach will never work for unit testing, because you still have a direct dependency on the sealed Application class. You've just moved it. You still need to call Application.SomeMethod(), which is a concrete method; you are supposed to depend only on the interface, not anything concrete.
What would work
In theory, the "right" way to do this is to wrap everything. So instead of exposing Application as a property, you keep it private; instead, you expose wrapped versions of the methods, like this:
public interface IApplication
{
void SomeMethod(string input);
}
public class ApplicationWrapper : IApplication
{
protected readonly Application _application;
public ApplicationWrapper()
{
_application = Application.GetInstance();
}
public void SomeMethod(string input)
{
_application.SomeMethod(input);
}
}
Then you'd call it like this:
var a = new ApplicationWrapper();
a.SomeMethod("Real argument");
Or in a full class with DI, it would look like this:
class ClassUnderTest
{
protected readonly IApplication _application; //Injected
public ClassUnderTest(IApplication application)
{
_application = application; //constructor injection
}
public void MethodUnderTest()
{
_application.SomeMethod("Real argument");
}
}
How to unit test
In your unit test, you can now mock the IApplication with a new class, e.g.
class ApplicationStub : IApplication
{
public string TestResult { get; set; } //Doesn't exist in system under test
public void SomeMethod(string input)
{
this.TestResult = input;
}
}
Notice this class has absolutely no dependency on Application. So you no longer need to call new on it, or call its factory method, at all. For unit testing purposed, you just need to ensure it gets called properly. You can do this by passing in the stub and checking the TestResult afterward:
//Arrange
var stub = new ApplicationStub();
var c = ClassUnderTest(stub);
//Act
c.MethodUnderTest("Test Argument");
//Assert
Assert.AreEqual(stub.TestResult, "Test Argument");
It's a bit more work to write the full wrapper (especially if it has a lot of methods), but you can generate a lot of that code with reflection or with third party tools. And it allows you full unit testing, which is the whole idea behind switching to that IApplication interface to begin with.
TLDR:
Instead of
IApplication wrapper = new ApplicationWrapper();
wrapper.Application.SomeMethod();
you should use
IApplication wrapper = new ApplicationWrapper();
wrapper.SomeMethod();
to remove the dependency on the concrete type.
You don't normally mock or fake static methods such as Application.Connect. Just partition the code under test so that it takes an already created IApplication object.
I was hoping that by using AutoFixture and NSubstitue, I could use the best of what each have to provide. I have had some success using NSubstitute on its own, but I am completely confused on how to use it in combination with AutoFixture.
My code below shows a set of things I am trying to accomplish, but my main goal here is to accomplish the following scenario: Test the functionality of a method.
I expect the constructor to be called with random values (except maybe one - please read point 2.).
Either during construction or later, I want to change value of a property -Data.
Next call Execute and confirm the results
The test that I am trying to get working is: "should_run_GetCommand_with_provided_property_value"
Any help or reference to an article that shows how NSubstitue and AutFixture SHOULD be used, would be great.
Sample Code:
using FluentAssertions;
using NSubstitute;
using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoNSubstitute;
using Xunit;
namespace RemotePlus.Test
{
public class SimpleTest
{
[Fact]
public void should_set_property_to_sepecified_value()
{
var sut = Substitute.For<ISimple>();
sut.Data.Returns("1,2");
sut.Data.Should().Be("1,2");
}
[Fact]
public void should_run_GetCommand_with_provided_property_value()
{
/* TODO:
* How do I create a constructor with AutoFixture and/or NSubstitute such that:
* 1. With completely random values.
* 2. With one or more values specified.
* 3. Constructor that has FileInfo as one of the objects.
*
* After creating the constructor:
* 1. Specify the value for what a property value should be - ex: sut.Data.Returns("1,2");
* 2. Call "Execute" and verify the result for "Command"
*
*/
// Arrange
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
// var sut = fixture.Build<Simple>().Create(); // Not sure if I need Build or Freeze
var sut = fixture.Freeze<ISimple>(); // Note: I am using a Interface here, but would like to test the Concrete class
sut.Data.Returns("1,2");
// Act
sut.Execute();
// Assert (combining multiple asserts just till I understand how to use NSubstitue and AutoFixture properly
// sut.Received().Execute();
sut.Data.Should().Be("1,2");
sut.Command.Should().Be("1,2,abc");
// Fails with : FluentAssertions.Execution.AssertionFailedExceptionExpected string to be "1,2,abc" with a length of 7, but "" has a length of 0.
}
}
public class Simple : ISimple
{
// TODO: Would like to make this private and use the static call to get an instance
public Simple(string inputFile, string data)
{
InputFile = inputFile;
Data = data;
// TODO: Would like to call execute here, but not sure how it will work with testing.
}
// TODO: Would like to make this private
public void Execute()
{
GetCommand();
// Other private methods
}
private void GetCommand()
{
Command = Data + ",abc";
}
public string InputFile { get; private set; }
public string Data { get; private set; }
public string Command { get; private set; }
// Using this, so that if I need I can easliy switch to a different concrete class
public ISimple GetNewInstance(string inputFile, string data)
{
return new Simple(inputFile, data);
}
}
public interface ISimple
{
string InputFile { get; } // TODO: Would like to use FileInfo instead, but haven't figured out how to test. Get an error of FileNot found through AutoFixture
string Data { get; }
string Command { get; }
void Execute();
}
}
I haven't really used AutoFixture much, but based on some reading and a bit of trial and error, I think you're misinterpreting what it will and won't do for you. At a basic level, it'll let you create a graph of objects, filling in values for you based around the objects constructors (and possibly properties but I haven't looked into that).
Using the NSubstitute integration doesn't make all of the members of your class into NSubstitute instances. Instead, it gives the fixture framework the ability to create abstract / interface types as Substitutes.
Looking at the class you're trying to create, the constructor takes two string parameters. Neither of these is an abstract type, or an interface so AutoFixture is just going to generate some values for you and pass them in. This is AutoFixture's default behaviour and based on the answer linked to by #Mark Seemann in the comments this is by design. There are various work arounds proposed by him there that you can implement if it's really important for you to do so, which I won't repeat here.
You've indicated in your comments that you really want to pass a FileInfo into your constructor. This is causing AutoFixture a problem, since its constructor takes a string and consequently AutoFixture is supplying a random generated string to it, which is a non-existent file so you get an error. This seems like a good thing to try to isolate for testing so is something that NSubstitute might be useful for. With that in mind, I'm going to suggest that you might want to rewrite your classes and test something like this:
First up create a wrapper for the FileInfo class (note, depending on what you're doing you might want to actually wrap the methods from FileInfo that you want, rather than exposing it as a property so that you can actually isolate yourself from the filesystem but this will do for the moment):
public interface IFileWrapper {
FileInfo File { get; set; }
}
Use this in your ISimple interface instead of a string (notice I've removed Execute since you don't seem to want it there):
public interface ISimple {
IFileWrapper InputFile { get; }
string Data { get; }
string Command { get; }
}
Write Simple to implement the interface (I haven't tackled your private constructor issue, or your call to Execute in the constructor):
public class Simple : ISimple {
public Simple(IFileWrapper inputFile, string data) {
InputFile = inputFile;
Data = data;
}
public void Execute() {
GetCommand();
// Other private methods
}
private void GetCommand() {
Command = Data + ",abc";
}
public IFileWrapper InputFile { get; private set; }
public string Data { get; private set; }
public string Command { get; private set; }
}
And then the test:
public void should_run_GetCommand_with_provided_property_value() {
// Arrange
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
// create and inject an instances of the IFileWrapper class so that we
// can setup expectations
var fileWrapperMock = fixture.Freeze<IFileWrapper>();
// Setup expectations on the Substitute. Note, this isn't needed for
// this test, since the sut doesn't actually use inputFile, but I've
// included it to show how it works...
fileWrapperMock.File.Returns(new FileInfo(#"c:\pagefile.sys"));
// Create the sut. fileWrapperMock will be injected as the inputFile
// since it is an interface, a random string will go into data
var sut = fixture.Create<Simple>();
// Act
sut.Execute();
// Assert - Check that sut.Command has been updated as expected
Assert.AreEqual(sut.Data + ",abc", sut.Command);
// You could also test the substitute is don't what you're expecting
Assert.AreEqual("pagefile.sys", sut.InputFile.File.Name);
}
I'm not using fluent asserts above, but you should be able to translate...
I actually managed to find a solution by realizing that I don't need to use AutoFixture for my current scenario.
I had to make some changes to my code though:
Added a default constructor.
Marked the methods and properties I want to provide a default value for as "virtual".
Ideally, I do not want to do these things, but it is enough to get me started and keep me moving forward for now.
Links that helped a lot:
Partial subs and test spies
Partial subs with nsubstitute
Modified code:
using FluentAssertions;
using NSubstitute;
using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoNSubstitute;
using Xunit;
using Xunit.Abstractions;
namespace Try.xUnit.Tests
{
public class TestingMethodCalls
{
private readonly ITestOutputHelper _output;
public TestingMethodCalls(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void should_set_property_to_sepecified_value()
{
var sut = Substitute.For<ISimple>();
sut.Data.Returns("1,2");
sut.Data.Should().Be("1,2");
}
[Fact (Skip="Don't quite understand how to use AutoFixture and NSubstitue together")]
public void should_run_GetCommand_with_provided_property_value_old()
{
/* TODO:
* How do I create a constructor with AutoFixture and/or NSubstitute such that:
* 1. With completely random values.
* 2. With one or more values specified.
* 3. Constructor that has FileInfo as one of the objects.
*
* After creating the constructor:
* 1. Specify the value for what a property value should be - ex: sut.Data.Returns("1,2");
* 2. Call "Execute" and verify the result for "Command"
*
*/
// Arrange
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
// var sut = fixture.Build<Simple>().Create(); // Not sure if I need Build or Freeze
var sut = fixture.Freeze<ISimple>(); // Note: I am using a Interface here, but would like to test the Concrete class
sut.Data.Returns("1,2");
// Act
sut.Execute();
// Assert (combining multiple asserts just till I understand how to use NSubstitue and AutoFixture properly
// sut.Received().Execute();
sut.Data.Should().Be("1,2");
sut.Command.Should().Be("1,2,abc");
// Fails with : FluentAssertions.Execution.AssertionFailedExceptionExpected string to be "1,2,abc" with a length of 7, but "" has a length of 0.
}
/* Explanation:
* Create a construtor without any arguments.
* Had to create a parameterless constructor just for testing purposes (would like to improve on this)
* Specify a default value for the desired method or property.
* It is necessary that the property or method has to be virtual.
* To specify that the based mehod should be call use the "DoNotCallBase" before the "Returns" call
*/
[Fact]
public void should_run_GetCommand_with_provided_Method_value()
{
// Arrange
var sut = Substitute.ForPartsOf<Simple>();
sut.When(x => x.GetData()).DoNotCallBase();
sut.GetData().Returns("1,2");
// Act
sut.Execute();
// Assert
sut.Received().GetData();
sut.Data.Should().Be("1,2");
sut.Command.Should().Be("1,2,abc");
}
[Fact]
public void should_run_GetCommand_with_provided_Property_value()
{
// Arrange
var sut = Substitute.ForPartsOf<Simple>();
sut.When(x => { var data = x.Data; }).DoNotCallBase();
sut.Data.Returns("1,2");
// Act
sut.Execute();
// Assert
sut.Received().GetData();
_output.WriteLine(sut.Command);
sut.Data.Should().Be("1,2");
sut.Command.Should().Be("1,2,abc");
}
}
public class Simple : ISimple
{
public Simple(){}
// TODO: Would like to make this private and use the static call to get an instance
public Simple(string inputFile, string data)
{
InputFile = inputFile;
InputData = data;
// TODO: Would like to call execute here, but not sure how it will work with testing.
}
public virtual string GetData()
{
// Assume some manipulations are done
return InputData;
}
// TODO: Would like to make this private
public void Execute()
{
Data = GetData();
GetCommand();
// Other private methods
}
private void GetCommand()
{
Command = Data + ",abc";
}
string InputData { get; set; }
public string InputFile { get; private set; }
public virtual string Data { get; private set; }
public string Command { get; private set; }
// Using this, so that if I need I can easliy switch to a different concrete class
public ISimple GetNewInstance(string inputFile, string data)
{
return new Simple(inputFile, data);
}
}
public interface ISimple
{
string InputFile { get; } // TODO: Would like to use FileInfo instead, but haven't figured out how to test. Get an error of FileNot found through AutoFixture
string Data { get; }
string Command { get; }
void Execute();
}
}
I'm posting this as a separate answer because it's more a critique of approach, than direct answer to your original question. In my other answer I've tried to directly answer your AutoFixture/NSubstitute questions assuming that you are currently trying to learn these to frameworks.
As it stands, you don't really need to use either of these frameworks to achieve what you are doing and in some ways it's easier not to. Looking at this test:
public void should_set_property_to_sepecified_value()
{
var sut = Substitute.For<ISimple>();
sut.Data.Returns("1,2");
sut.Data.Should().Be("1,2");
}
This isn't actually testing your class at all (other than compilation checks), really you're testing NSubstitute. You're checking that if you tell NSubstitute to return a value for a property that it does.
Generally speaking, try to avoid mocking the class that you're testing. If you need to do it, then there is a good chance that you need to rethink your design. Mocking is really useful for supplying dependencies into your class that you can control in order to influence the behaviour of your class. If you start modifying the behaviour of the class you're testing using mocks then it's very easy to get confused about what you're actually testing (and to create very brittle tests).
Because you're dealing with basic types and not nested objects, at the moment it's easy to create + test your objects without using something like AutoFixture/NSubstitute. You code could look like this, which seems to be closer to what you're hoping for:
public interface ISimple {
string InputFile { get; }
string Data { get; }
string Command { get; }
}
public class Simple : ISimple {
private Simple(string inputFile, string data) {
InputFile = inputFile;
Data = data;
}
private void Execute() {
GetCommand();
}
private void GetCommand() {
Command = Data + ",abc";
}
public string InputFile { get; private set; }
public string Data { get; private set; }
public string Command { get; private set; }
// Note.. GetNewInstance is static and it calls the Execute method
static public ISimple GetNewInstance(string inputFile, string data) {
var simple = new Simple(inputFile, data);
simple.Execute();
return simple;
}
}
And your test would look like this:
[Test]
public void should_run_GetCommand_with_provided_property_value() {
// Arrange
var inputFile = "someInputFile";
var data = "1,2";
var expectedCommand = "1,2,abc";
// Act
// Note, I'm calling the static method to create your instance
var sut = Simple.GetNewInstance(inputFile, data);
// Assert
Assert.AreEqual(inputFile, sut.InputFile);
Assert.AreEqual(data, sut.Data);
Assert.AreEqual(expectedCommand, sut.Command);
}
I've left the Execute outside of the objects constructor because it feels a bit like it's going to be doing too much. I'm not a huge fan of doing a lot other than basic setup in constructors particularly if there's a chance you might end up calling virtual methods. I've also made GetNewInstance static so that it can be called directly (otherwise you have to create a Simple to call GetNewInstance on it which seems wrong)...
Whilst I've shown above how your code could work as you want it so, I'd suggest that you might want to change the Simple constructor to internal, rather than private. This would allow you to create a factory to create the instances. If you had something like this:
public interface IMyObjectFactory {
ISimple CreateSimple(string inputFile, string data);
}
public class MyObjectFactory {
ISimple CreateSimple(string inputFile, string data) {
var simple = new Simple(inputFile, data);
simple.Execute();
return simple;
}
}
This allows you to safely constructor objects that need methods called on them. You can also inject substitutes of the IMyObjectFactory that returns a substitute of ISimple in future classes that are dependent on the Simple class. This helps you to isolate your classes from the underlying class behaviour (which might access the file system) and makes it easy for you to stub responses.
I have a class that I would like to test with Unit tests. It has some logic to look for some values in the local xml file, and if the value is not found it will read some external source (SqlServer DB). But during Unit testing I don't want this component to interact with Sql Server at all. During unit testing I would like to replace SqlServer implementation of the External source reader to some Noop reader. What is the good approach to achieve that? Important note: I can't define constructor that accepts instance of reader type since it is client facing API and I want to limit what they can do with my classes.
I am currently using few ways in Unit tests:
Use reflection to set value of the private/protected property to my mocked implementation of the reader
Define factory that will create concrete class. Register factory in Unity container & class under test will get factory object from DI container and instantiate reader according to my needs
Subclass class-under-test and set property there.
But none of them seem to be clean enough to me. Are there any better ways to achieve that?
Here is the sample code to demonstrate example of the class-under-the-test:
namespace UnitTestProject1
{
using System.Collections.Generic;
using System.Data.SqlClient;
public class SomeDataReader
{
private Dictionary<string, string> store = new Dictionary<string, string>();
// I need to override what this property does
private readonly IExternalStoreReader ExternalStore = new SqlExternalStoreReader(null, false, new List<string>() {"blah"});
public string Read(string arg1, int arg2, bool arg3)
{
if (!store.ContainsKey(arg1))
{
return ExternalStore.ReadSource().ToString();
}
return null;
}
}
internal interface IExternalStoreReader
{
object ReadSource();
}
// This
internal class SqlExternalStoreReader : IExternalStoreReader
{
public SqlExternalStoreReader(object arg1, bool arg2, List<string> arg3)
{
}
public object ReadSource()
{
using (var db = new SqlConnection("."))
{
return new object();
}
}
}
internal class NoOpExternalStoreReader : IExternalStoreReader
{
public object ReadSource()
{
return null;
}
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var objectToTest = new SomeDataReader();
objectToTest.Read("", -5, false); // This will try to read DB, I don't want that.
}
}
In this case, you can use the InternalsVisibleTo attribute, which exposes all internal members to friend assemblies.
You could start by creating a separate internal constructor overload, which can accept a different instance of IExternalStoreReader:
public class SomeDataReader
{
// publicly visible
public SomeDataReader()
: this(new SqlExternalStoreReader(...))
{ }
// internally visible
internal SomeDataReader(IExternalStoreReader storeReader)
{
ExternalStore = storeReader;
}
...
}
And then allow the unit testing assembly to access internal members by adding the InternalsVisibleTo attribute to your AssemblyInfo.cs:
[assembly: InternalsVisibleTo("YourUnitTestingAssembly")]
If you're really concerned about people trying to access your internal members, you can also use strong naming with the InternalsVisibleTo attribute to ensure no one tries to impersonate your unit testing assembly.
The simple answer is: change your code. Because you have a private readonly field that creates its own value, you cannot change that behaviour without getting really hacky, if at all. So instead, don't do it that way. Change the code to:
public class SomeDataReader
{
private Dictionary<string, string> store = new Dictionary<string, string>();
private readonly IExternalStoreReader externalStore;
public SomeDataReader(IExternalStoreReader externalStore)
{
this.externalStore = externalStore;
}
In other words, inject the IExternalStoreReader instance into the class. That way you can create a noop version for unit tests and the real one for production code.
If you're compiling the complete code yourself, you could create a fake SqlExternalStoreReader with a stubbed implementation inside your unit test project.
This stub implementation allows you to access all fields and forward calls to your mocking framework/unit test
I am writing Unit tests for the following class legacy class
Class myLegacyClassPresenter
{
private MethodA(){}
private propertyA {get; set;}
private MethodB(YearValue value){}
//some more properties & method goes here
private struct YearValue
{
public static int One { get { return 365; } }
public static int Two { get { return 730; } }
}
}
Here is my unit test.
public void mytest()
{
//some initializations
var view = myLegacyView();
var service = new Mock<ILegacyService>();
var presenter = new myLegacyClassPresenter(view, service);
var privateObject = new PrivateObject(presenter);
//I can access all private methods and properties as follows
privateObject.invoke("MethodA");
privateObject.GetProperty("propertyA")
// But How can I get the the Struct Year value to pass to MethodB
privateObject.Invoke("MethodB", new object[]{YearValue.One}); //Compile Error for YearValue
//I can't change in the class, One way is to define the same struct locally, Is there any other approach we can have to achieve the same result.
}
Classic example which shows how if you cannot unit test a particular component, REFACTOR the component!
This is where is love what any mocking framework enforces you to do - write decoupled code.
Couple of things:
Testing private methods should be seriously reconsidered. You break encapsulation the moment you test private methods and properties.
In your example, the myLegacyClassPresenter class is very tightly coupled with the YearValue struct. You could decouple it using dependency injection.
If you want to create an instance of the struct you can use something like the following
var theType = Type.GetType("MyNamespace.myLegacyClassPresenter+YearValue");
var parameter = Activator.CreateInstance(theType);
privateobject.Invoke("MethodB", new object[]{parameter});
If you need to pass in YearValue.One, then theType.GetMember() can be used to get the value.
I am working on a brownfield application and am currently refactoring part of it. I am trying to do this in a TDD fashion but am running into a problem. Part of the code I am testing does
var siteLanguages = from sl in SiteSettings.GetEnabledSiteLanguages() select sl.LanguageID;
where GetEnabledLanguages has the following signature
public static List<LanguageBranch> GetEnabledSiteLanguages();
it in turns calls data access code to retrieve the relevant information. Up untill now I have used a interface and DI to use a different stub implementation for these kind of dependencies during unit testing. But since the GetEnabledSiteLanguages method is static this will not work. What is the "correct" way to do it in this case?
you could create a object which implements an interface and inject an implementation of this into the class which uses the SiteSettings class. The interface declare the method with the same signature as the static method(s) you need to intercept. Then you could mock out the interface for tests and create a single implementation which delegates to the static method for the actual code:
public interface ISiteSettings
{
public List<LanguageBranch> GetEnabledSiteLanguages()
}
public class ActualSiteSettings : ISiteSettings
{
public List<LanguageBranch> GetEnabledSiteLanguages()
{
return SiteSettings.GetEnabledSiteLanguages();
}
}
... in the dependent class:
public class DependentClass
{
private ISiteSettings m_siteSettings;
public DependentClass(ISiteSettings siteSettings)
{
m_siteSettings=siteSettings;
}
public void SomeMethod
{
var siteLanguages = from sl in m_siteSettings.GetEnabledSiteLanguages() select sl.LanguageID;
}
}
What about making your method such as:
public static Func<List<LanguageBranch>> GetEnabledSiteLanguages = () => {
//your code here
};
Now it becomes first class object (as Func delegate) and a stub can replace it
Look at Moles framework.
You can use tools like JustMock, TypeMock or moles. These tools allow you to mock everythings like static methods.