I am attempting to mock (using Moq) a classes and interfaces that are defined in a third party SDK. Here's a simplified example of what they look like:
public interface IVehicle
{
string Type { get; }
}
public class Vehicle
{
public string Type { get; }
}
public class Jeep : Vehicle, IVehicle
{
}
I can easily mock the interface like so:
var mockVehicle = new Mock<IVehicule>(MockBehavior.Strict);
mockVehicle
.SetupGet(v => v.Type)
.Returns("My custom vehicle");
but I need to write a unit test specific to the Jeep class and I can't figure out how to mock it.
My first attempt:
var mockJeep = new Mock<Jeep>(MockBehavior.Strict);
yielded the following error:
Moq.MockException: IVehicle.Type invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
which is understandable since I haven't setup the Type property.
My second attempt:
var mockJeep = new Mock<Jeep>(MockBehavior.Strict);
mockJeep
.SetupGet(v => v.Type)
.Returns("Jeep");
yielded the following error message:
System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: v => v.Type
which is also understandable since the Type property on the Vehicle class is not virtual.
So my question is: is there a way to setup the Type property when mocking the Jeep class?
The best Moq can do in this case is create a proxy as a derived class of Jeep but it cannot override the non-virtual Type property. Remember that when you attempt to create a Mock with Moq, the framework generates a class that either implements the target interface or derives from the target class.
Microsoft Fakes work well with Moq provided that you have the Visual Studio license level to access it.
Since this is a rather generalized question, I'm going to suggest a different approach. Mocking / Faking / Stubbing a class or interface that you don't control is generally difficult. Furthermore, this typically leads to replicating someone else's functionality in your mock instance.
A better approach is to isolate interaction with the external library into a wrapping class that you control the interface and implementation of. This will allow you to easily mock/fake/stub your interface for testing consumers of your interface.
This still leaves the question of what to do with the isolation layer class. For this, you'll need to do more of an integration test that actually exercises both your wrapping class and the external class. Then, verify that you get the expected behavior from the combination of your class and the external classes you're wrapping.
So my question is: is there a way to setup the Type property when mocking the Jeep class?
The short answer is no, you cannot Mock a non virtual member using Moq.
However, I don't think there's any reason in this case to mock anything, since there isn't any behaviour to mock. The only member you have there is a simple string property. So even if you could, you probably shouldn't.
If you are trying to test the Jeep class, just test it directly
without mocking any of its members; mocking should only be used when you need to control the behaviour of one of the dependencies of the System Under Test (SUT)
If you are passing the Jeep
class to another method as a dependency in order to test that method, you can just
new up a Jeep instance and pass it in your test in this case; since it doesn't
have any boundary-crossing behaviours (network calls, etc) then there
is no need to mock it.
You might also consider that if it's the second case, you ought to be able to pass an IVehicle instead of a Jeep, in which case mocking is back on the table (although as mentioned, there is no apparent need in this case)
Incidentally, your hierarchy looks a little off - why does Vehicle not itself implement IVehicle?
i.e.
public interface IVehicle
{
string Type { get; }
}
public class Vehicle: IVehicle
{
public string Type { get; }
}
public class Jeep : Vehicle
{
}
Then Jeep will already be both a Vehicle and an IVehicle :)
disclaimer: I work at Typemock.
By using Typemock Isolator you will be able to mock non-virtual methods and won't need to change your code in order to do so, in this specific example you can fake an instance of Jeep and then modify his methods behavior.
Here is an example for a test that mock Jeep:
[TestMethod]
public void CallFakeJeepType_WillReturnWantedString()
{
var jeep = Isolate.Fake.Instance<Jeep>();
Isolate.WhenCalled(() => jeep.Type).WillReturn("fake jeep");
var result = Jeep.DoSomthing(jeep);
Assert.AreEqual("fake jeep", result);
}
note: if the Jeep.Type had a setter as well you could use typemock's True property and the test will look like this
var jeep = Isolate.Fake.Instance<Jeep>();
jeep.Type = "fake jeep";
Related
We've started to introduce some behavior tests that try to test some of out software modules like a complete black box.
This test suite was written using inheritance from base test class for easier organization.
Now we'd like to reuse this test suite for the testing of another interface-compatible module.
The solution we were able to find was to inherit the test class, and implement another constructor.
I'd like to confirm that there's no better option, because writing duplicate inherited classes for each of the test suite class seems wrong.
[TestClass]
public class RouModel_Basic_RunnerBasic : ROUModelTest_Basic
{
public RouModel_Basic_RunnerBasic() : base()
{
//init basic model here
model = basicModel;
}
}
[TestClass]
public class RouModel_Basic_RunnerOther : ROUModelTest_Basic
{
public RouModel_Basic_RunnerOther() : base()
{
//init other model here
model = otherModel;
}
}
public class ROUModelTest_Basic : RouModelTest
{
[TestMethod]
public void TestABC()
{
string input = "abc"
var result = model.run(input);
Assert.AreEqual("123", result);
}
}
public class RouModelTest
{
protected IModelTest model;
...
}
If you just want to re-use the test code as-is but with a different module under test, inheritance seems to be the most straightforward, since you will need a separate test method for each test, and inheritance is the only way to do that without having to type them yourself. This shouldn't introduce any duplication, since you only have to re-implement the parts that are actually different in each subclass.
If your issue is with the fact that you are building your test fixture in the test case class constructor, an alternative would be to apply the Template Method design pattern to your test methods, and add a virtual creation method for the module under test that subclasses can override to create instances of the specific module you want them to test. Alternatively, you could create a test setup method and mark it with the appropriate attribute, as described in this answer.
That being said, if you really want to keep them all in the same test case class, you might be able to do so if you implement creation methods for the individual modules under test on your base test case class, and then pass the names of those methods to your test methods and call them using reflection. There should be an attribute that allows you to pass arguments to test methods, which is discussed in this answer. However, the feasibility of this approach is just speculation on my part, and you might run the risk of making your tests more obscure.
First, let me introduce you my project.
We are developping an app in which user can work with programs. As programs I mean list of instructions for a confidential use.
There are different types of Programs all inheriting from the Program abstract base class.
As the user can create different types of program, we developped a ProgramManager that can instantiante any type of Program by its type. We don't need to instantiate the abstract class but all the concrete classes (and it works) but as concrete Program have same methods (AddNewChannel, Save, ...) we handle them like Programs.
Here's a sample of code:
public Program CreateProgram(Type type)
{
Program program = Activator.CreateInstance(type) as Program;
program.Directory = ProgramsPath;
int nbChannels = 2; //not 2 but a long line searching the correct number where it is.
for (int i = 1; i <= nbChannels; i++)
{
program.AddNewChannel(i);
}
program.Save();
return program;
}
What I now have to do is test this function and I don't want to duplicate the unitTests I already made for the different Program classes.
As an example, here is one of my test functions (for the Save method) with it's init. I store the types I need to test in a xml file.
[TestInitialize]
public void TestInitialize()
{
if (!TestContext.TestName.StartsWith("GetKnownTypes"))
type = UnitTestsInitialization.applicationHMIAssembly.GetType((string)TestContext.DataRow["Data"]);
}
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
"|DataDirectory|\\" + DATA_FILE, "Row",
DataAccessMethod.Sequential)]
public void SavedProgramCreatesFile()
{
Program program = Activator.CreateInstance(type) as Program;
program.Name = "SavedProgramCreatesFile";
program.Directory = DIRECTORY;
program.Save();
string savedProgramFileName = program.GetFilePath();
bool result = File.Exists(savedProgramFileName);
Assert.IsTrue(result);
}
All my concrete Program classes have been tested separatly.
Thereby, I would like to test if the following methods program.AddNewChannel and program.Save are called.
I gave a look at Moq but the first problem is that the method Save is not abstract.
Also, using Activator doesn't allow me to make a Mock<Program>.
I tried the following in a unit test in order to try to instantiate the mock and use it like a program:
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
"|DataDirectory|\\" + DATA_FILE, "Row",
DataAccessMethod.Sequential)]
public void CreateProgram_CallsProgramSaveMethod()
{
Mock<Program> mock = new Mock<Program>();
mock.Setup(p => p.AddNewChannel(It.IsAny<int>()));
Program program = pm.CreateProgram(mock.Object.GetType());
mock.Verify(p => p.Save());
mock.Verify(p => p.GetFilePath(It.IsAny<string>()));
mock.Verify(p => p.AddNewChannel(It.IsAny<int>()), Times.Exactly(ProgramManager.NB_MACHINE_CHANNELS));
Assert.IsNotNull(program);
program.DeleteFile();
}
Which was inspired by this question: How to mock An Abstract Base Class
And it works until it reaches the line program.AddNewChannel(i); in the for loop. The error is the following:
System.NotImplementedException: 'This is a DynamicProxy2 error: The interceptor attempted to 'Proceed' for method 'Void AddNewChannel(Int32)' which is abstract. When calling an abstract method there is no implementation to 'proceed' to and it is the responsibility of the interceptor to mimic the implementation (set return value, out arguments etc)'
It seems that the setup doesn't work but I might understand why. (I try to instantiate a subtype of Proxy which doesn't implement verify method)
I also tried to use a Proxy over my program class which would implement an interface which would contain the methods I needed but the problem here is the activator again.
Can anyone suggest me any way of testing those method calls ? (Even if I need to change my method CreateProgram)
I gave a look here: How to mock non virtual methods? but I am not sure this would be applicable to my problem.
I use MSTests for my unittests.
NOTICE
Everything else works fine. All my other tests pass without troubles and my code seems to work (Tested by hand).
Thanks in advance.
The root cause of the problem is that you're using a type as a parameter, which you then use to create an instance of this type. However, you're passing in the type of an abstract class, which is specifically not made for instantiating. You need to work with the concrete classes directly.
Thereby, I would like to test if the following methods program.AddNewChannel and program.Save are called.
That's not sufficient as a test. You want to test whether these methods work as expected, not just if they're called and then assume that they work.
What you're describing is a (very rudimentary) integration test, not a unit test.
I don't want to duplicate the unitTests I already made for the different Program classes
This is a very dangerous decision. Part of the idea behind unit testing is that you create separate tests for different (concrete) objects. The tests need to be as segregated as is reasonably possible. You're trying to reuse testing logic, which is a good thing, but it needs to be done in a way that it does not compromise your test segregation.
But there are ways to do it without compromising your test segregation. I only have testing experience with NUnit but I assume a similar approach works in other frameworks as well.
Assume the following:
public abstract class Program
{
public bool BaseMethod() {}
}
public class Foo : Program
{
public bool CustomFooMethod() {}
}
public class Bar : Program
{
public bool CustomBarMethod() {}
}
Create an abstract class testing method:
[TestFixture]
[Ignore]
public class ProgramTests
{
public virtual Program GetConcrete()
{
throw new NotImplementedException();
}
[Test]
public void BaseMethodTestReturnsFalse()
{
var result = GetConcrete().BaseMethod();
Assert.IsFalse(result);
}
}
[Ignore] ensures that the ProgramTests class does not get tested by itself.
Then you inherit from this class, where the concrete classes will be tested:
[TestFixture]
public class FooTests
{
private readonly Foo Foo;
public FooTests()
{
this.Foo = new Foo();
}
public overrides Program GetConcrete()
{
return this.Foo;
}
[Test]
public void CustomFooMethodTestReturnsFalse()
{
var result = this.Foo.CustomFooMethod();
Assert.IsFalse(result);
}
}
BarTests is similarly implemented.
NUnit (presumably other testing frameworks as well) will discover all inherited tests and will run those tests for the derived class. Every class that derives from ProgramTests will therefore always include the BaseMethodTestReturnsTrue test.
This way, your base class' tests are reusable, but each concrete class will still be tested separately. This maintains your test separation, while also preventing you having to copy/paste test logic for every concrete class.
I also noticed this:
Mock<Program> mock = new Mock<Program>();
mock.Setup(p => p.AddNewChannel(It.IsAny<int>()));
Program program = pm.CreateProgram(mock.Object.GetType());
I don't understand the purpose of this code. How is it any different from simply doing:
Program program = pm.CreateProgram(typeof(Program).GetType());
As far as I can see, both the mock and its setup are irrelevant since you're only looking at its type and then having CreateProgram() create a new object for you anyway.
Secondly, and this refers back to my example of testing the concrete classes, you shouldn't be testing with Program directly, you should be testing your derived program classes (Foo and Bar).
This is the root cause of the problem. You're using a type as a parameter, which you then use to create an instance of this type. However, you're passing in the type of an abstract class, which is specifically not made for instantiating. You need to work with the concrete classes directly.
Create a wrapper interface and class around Activator, then pass the type to that:
public interface IActivatorWrapper
{
object CreateInstance(Type type);
}
public class ActivatorWrapper : IActivatorWrapper
{
public object CreateInstance(Type type)
{
return Activator.CreateInstance(type);
}
}
Use this instead of Activator directly, then mock the IActivatorWrapper to return whatever mock object you want.
Another idea to help with your problem would be to add an IProgram interface to your abstract Program class, then use that to refer to your concrete Program instances. This might also help you, should you ever want to write a concrete Program with a different base class.
I have read that you need to define interfaces in order to mock types but I am not sure how to interpret that.
For example, to mock FileSystem, instead of directly calling some I/O method, I can pass the object to the method and then mock it when calling from my test.
Why are unit test examples (like the one from SO question below), use interfaces?
void DoIt(IZipper zipper, IFileSystem fileSystem, IDllRunner runner)
{
string path = zipper.Unzip(theZipFile);
IFakeFile file = fileSystem.Open(path);
runner.Run(file);
}
Could I not simply use arguments of respective types, and inject the object then?
E.g. in the GUICE guide, they advise to remove constructor work (e.g. no field inicialization with "new" keyword), but use parameters istead.
It depends on your mocking framework. Using Moq, you can mock concrete types as long as they aren't sealed and the members you want to mock are virtual. Interfaces are generally preferred because their members don't need to (and can't) be marked as virtual. (There are other reasons to prefer interfaces such as to keep the coupling between your classes loose)
https://github.com/Moq/moq4/wiki/Quickstart
Update
Generally you will mock an instance of a type. Therefore you can't test static method calls like FileStream.Open because there is no instance to mock.
Update
Frameworks like Moq rely on inheritance to generate the mocks. That's why methods need to be virtual. If you want to mock static or private methods, try Microsoft Fakes.
https://msdn.microsoft.com/en-us/library/hh549175.aspx
It is not must to have interface as dependency but that's recommended and widely followed practice.
Using interface and base classes as dependency helps you creating lossely couple design.
Loosely coupled design makes it possible to create modules/layers of application without depending on the implementation details about other layer.
This also makes it super easy to test the piece of code in isolation without worrying about how other layer would work or react.
This type of testing is called unit testing.
If you have dependency on concrete class then you can't unit test code in isolation. Such tests are prone to fail whenever implementation of dependency changes. If your code is dependent on actual file system class or data access class which connects to actual db then there are chances that the unit tests will fail when file is not accessible or db server is down or data is currupted.
This even won't be called unit testing. It is called integration testing.
As I mentioned, while testing code in isolation you don't need to worry about how the dependency works. That's why, while unit testing the dependencies are mocked. Also dependencies must not be an interface. It can be a base class too. When you mock dependency, mocks do not have actual implementation of any of the functionality. How many ways you can create mocks, is a different topics altogether.
Using mocks, in unit testing, you just need to make sure that they behave per your expectations while you test the code your current class. So you ask the mock to behave the way you want, make sure that certain methods or properties of mock called, so that you can cover all the paths of the piece of code which you are testing.
Following is a simple example of Unit Testing with dependency.
public class ProductService
{
private IProductRepository repository;
public ProductService (IProductRepository repository)
{
this.repository = repository;
}
public Product GetProductById(int productId)
{
if(productId <= 0)
return null;
var product = this.repository.GetProductById(productId);
return product;
}
}
While Creating ProductService class, even if I don't have actual implementation of IProductRepository interface, I can still unit test ProductService class as following.
public class ProductServiceTests
{
ProductService serviceToTest;
IProductRepository productRepository;
public ProductServiceTests()
{
this.productRepository = Mock<IProductRepository>();
this.serviceToTest = new ProductService(productRepository);
}
public void GetProductByIdReturnsNullIfProductIdIsZero()
{
int productid = 0;
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Null);
}
public void GetProductByIdReturnsNullIfProductIdIsNegative()
{
int productid = -1;
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Null);
}
public void GetProductByIdReturnsProductIfProductIdIsPositive()
{
var productid = 1;
var product = new Product { Id = productId };
productRepository.Setup(repo => repo.GetProductById(productid)).Returns(product); //Making sure that GetProductById method of repository is called and return an object of product as this call is part of the code which I am testing right now.
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Not.Null);
Assert.That(product.Id, Is.EqualTo<int>(productid));
}
}
This is an example code to illustrate the unit testing. It might not build or run as expected and I apologies for that.
edit
Found an excellent article on mocking classes https://www.wrightfully.com/how-net-mocking-frameworks-work
This should clear doubts of how class mocking is different than the interface mocking.
I have an interface like this
public interface IConnection
{
Strategy Gc { get; }
bool IsConnected();
bool Connect();
}
I want to unit test methods of a class that uses this interface. Now I want to set Gc but it happens to be readonly. Is there a way to set Gc field without making changes to this interface class?
I am using MS fakes and Nsubstitute for unit testing. However, apparently none provides a solution. PrivateObject does not work either.
Changing Interface is not an option. Suggest better solutions.
With NSubstituteit is quite easy. First create a mock for your interface:
var mock = Substitute.For<IConnection>();
Now you can mock the member by setting any return-type for the property:
mock.Gc.Returns(Substitute.For<Strategy>());
Finally provide that mocked instance as parameter to the service depending on that instance, for example:
var target = new MyClassToTest();
target.DoSomething(mock); // mock is an instance of IConnection
Now whenever your method is called it returns a dumm-instance for Strategy. Of course you can also set any other arbitrary return-type within the Returns-statement. Just have a look at http://nsubstitute.github.io/help/set-return-value for further information.
I have a class that takes a MethodInfo instance and extracts some information from it, but I would like to mock this class. At the moment it is difficult because it takes a MethodInfo, so my plan was to create a wrapper for the MethodInfo class and implement an interface on it. For example:
public interface IMethodInfo
{
string Name { get; }
}
public class MethodInfoProxy : IMethodInfo
{
private readonly MethodInfo _method;
public MethodInfoProxy(MethodInfo method)
{
_method = method;
}
public string Name { get { return _method.Name; } }
}
public class MyClass
{
public MyClass(IMethodInfo method)
{
...
}
}
Another example would be the File.Exists method. The thought would be to create a IFile.Exists and put it on a FileProxy class that would simply delegate to File.Exists.
As I'm new to the whole unit testing world I would like to know if this would be considered a good approach to take?
You have two options here:
Use a mocking framework like Microsoft Moles or TypeMock Isolator that can mock static and sealed classes. This is great because you don't end up changing your code just to isolate the code under test from its dependencies.
Defining interfaces for behaviours that you want to mock, and then creating a default implementation that wraps a static call, or other difficult-to-test api. This is the approach you've suggested and one that I've used a lot. The key thing, when defining these interfaces is to pass the real/mock implementation of the interface into the test class via some form of dependency injection - usually constructor injection. Some people make the mistake of constructing the object within the class being tested and that makes it impossible to test. A good rule of thumb is that when you see objects being constructed in your business code, then that is a code smell - not always a bad thing, but definitely something to view with suspicion. There's a great video about this stuff: The Clean Code Talks - "Global State and Singletons".
There's a bit of a religious war between those who think testing shouldn't change the code and those that think it should. Dependency injection, which is essential if you are going to mock by creating interfaces, leads to code with high cohesion and loose coupling and an intuitive API. But the other approach isn't precluded from these benefits - it's just not so automatic.
I recommend trying to pull the dependencies out of the class - instead of supplying a MethodInfo (or a proxy), just supply the Name.
When that isn't practical, you can either write proxy classes that use an adapter interface (as you've suggested) or use a black-magic tool like TypeMock or Moles (just kidding about the black magic part: I just don't have any experience with them).
If you plan to use the proxy approach, be sure to take a look at the SystemWrapper library, which already handles about twenty classes from the .NET framwork.
You could create a wrapper around each of the class that you use but it would be extremely expensive. It's better to use a mocking framework such as the moles framework by Microsoft http://research.microsoft.com/en-us/projects/pex/ which can also stub out static methods.
A Mock class (or a fake class) would be a class you make to satisfy dependencies and make your test more deterministic by ruling out problems in your dependencies.
public interface IMethodInfo
{
string Name { get; }
}
Your mock class:
FakeMethodInfo : IMethodInfo
{
string Name {get {return "FakeMethod";}}
}
Now, in your unit test, pass the FakeMethodInfo class where you need an IMethodInfo.
The whole purpose is that you know FakeMethodInfo just returns a string so if something fails, it is not the problem.
Don't know what context MethodInfo has in your program. A better example would be
interface IUser
{
string UserName {get;}
}
If it were implemented in a class you would get the actual username from a data base.
Now, if you make a fake one, and pass it around, you kinda simulate a user logged in without a real user, and you rule out that any problem has to do with `IUser.
See this large answer I posted on why you would use mocking. And an example with Moq.:
Difference between Dependency Injection and Mocking framework (Ninject vs RhinoMock or Moq)
For faster creating of wrapper classes, you can use one of the Scaffold code generator I created.
https://www.nuget.org/packages/Digitrish.WrapperGenerator/
This will generate Interface that you can use to any mocking framework and concrete wrapper class for the real implementation.