I'm studying Microsoft Fakes to implement unit tests in a project of mine.
If i've understood correctly, i use stubs to set the behavior of external components (that implement interfaces) that the main component i want to test is dependent from.
I use shibs to simulate the behavior of specific pieces of code at runtime.
My goal is to test a method of a manager class that has dependencies to other components all implementing interfaces. This method, among the other things, calls a private method.
In the test method i need to force the result of that private method.
The scenario is similar to the following code:
public class MyManager : IMyManager {
private IMyDependentManager _myDependentManager;
public MyManager(IMyDependentManager myDependentManager) {
this._myDependentManager = myDependentManager;
}
public void MyMethodToTest(data1, data2,...) { // method to test
...
byte[] res = MyPrivateMethod(data1); // i want to set the result of this method in order to NOT execute it, otherwise the test will fail
...
}
private byte[] MyPrivateMethod(data1) {
}
}
Any suggestion on how to setup the test would be very helpful.
The implication from the question and the private method's signature is that you need to separate the concerns.
Consider what the responsibility of your manager class is. Now consider what that private method is doing. I suspect you will find that the private method is not something that the manager class is (directly) responsible for - it is doing something that the manager should be delegating.
Move that private method into a separate class (as a public method), and use dependency injection to give it to the manager class, I would suggest doing this via an interface.
Now when testing your manager, you can supply it's constructor with a mock of the new class's interface to return whatever you like.
Related
In our ASP.Net core application, we have many APIs which are calling public method from the service class.
Service class is implementing an Interface.
Each service method (depending upon complexity and requirement) may call any number of internal or private or helper methods.
While each of these internal/private/or helper methods are separately unit tested, how do we test the public service methods in such a way that we don't have to duplicate the code/effort that we have already spent in testing the internal/private/helper methods?
e.g. we can easily mock up the Interface methods to say the interface method expects these input arguments and returns bla bla (without actually calling the method). So, can a similar thing be done to internal/private/helper methods which are not part of Interfaces so that we don't have to actually call these methods real time, and can just 'Mock' them while testing the main method itself?
Well, actually you can mock your internal/private methods if they are virtual.
For example, having class like:
public class ClassUnderTest
{
public void MethodUnderTest() {
SubMethod();
}
protected virtual void SubMethod() {
}
}
You can mock it and test with:
var classMock = new Mock<ClassUnderTest>();
classMock.Setup(x => x.SubMethod());
var class = classMock.Object;
class.MethodUnderTest();
classMock.Verify(x => x.SubMethod(), Times.Once);
Still, it's not actually good approach. Usually, if you need to test such scenario, that means that your MethodUnderTest and class ClassUnderTest actually works as orchestrator for other functions and there is certain sense in extracting methods (that are called from MethodUnderTest) from ClassUnderTest to other classes to keep your architecture SOLID. ClassUnderTest will perform orchestration, while others classes will do there work.
BTW. Another bad thing is that if you mark your internal methods as protected virtual just to have ability to mock them, that a bit violates idea of unit-testing, where you should not add any special code to make it testable.
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.
I have this scenario: an interface with 2 methods
the 2 methods take requests and return response
Methods contain functionality inside (check permissions and validate request and get data from database using entity framework.
But I want to test the methods and not just the interface.
I've tested the interface successfully but now I want to enter the method and test inside it.
Code example:
public interface IMyInterface
{
[OperationContract]
responseObject GetData(Service<RequestObject> request);
}
public class MyConcreteClass : IMyInterface
{
public responseObject GetData(Service<RequestObject> request)
{
CheckForNull(request);
ValidateMethod(request);
//connect to db
using(var context = new contextEntity)
{
//get data
}
}
}
Now, I want to test the check nulls, permissions and data access, is it possible? Or do I have to extract interface from the internal methods?
PS, this is for my unit testing. I'm trying to eliminate external dependencies.
please explain in detail
Unit testing private methods should not be needed directly, only indirectly via public methods. If you think you testing a public method isn't enough precise, it might be that the method and the class are too complicated already.
In that case consider creating one or more new classes where the new code is located. That way you can unit test your code via public method. The added benefit is that your code is probably better in terms of Single responsibility principle.
The reason for mocking is so that you can control behaviour; in this case, I'm going to go out on a limb and guess that Service<RequestObject> doesn't actually have any behaviour, and therefore it doesn't actually need to be mocked. So it can probably just be passed as-is in any tests.
However, if it does have behaviour, and that behaviour crosses an architectural boundary (let's say in the GetData method you are calling some method on the request parameter that will make a network call, or access the file system, etc.) then you do need to mock it. But you can do that easily enough:
public interface IService<RequestObject>
{
//put method and property signatures of Service<RequestObject> here
}
public class ServiceObject:Service<RequestObject>, IService<RequestObject>
{
public ServiceObject(RequestObject request): base(request){
//or however the Service<Request> object is instantiated.
};
}
Then change GetData to take an IService<RequestObject>; now your calling code can instantiate a ServiceObject in place of a Service and pass it to the GetData method. Plus you can Mock any methods on the interface as you need. Obviously if you don't control the calling code, that's a problem since whoever is writing that code needs to do it, but that's a conversation you will need to have with them :)
In terms of testing the internal operations,you need to look at how you can abstract any dependent behaviours used by the GetData method - for example, the contextEntity, the CheckForNull, the ValidateMethod, etc - all of these are candidates to be extracted into their own abstractions and injected into the MyConcreteClass as dependencies, e.g.:
public class MyConcreteClass: IMyInterface
{
readonly INullChecker _nullChecker;
readonly IValidator _validator;
readonly IContextEntity _context;
public MyConcreteClass(INullChecker nullChecker, IValidator validator, IContextEntity _context)
{
_nullChecker = nullChecker;
_validator = validator;
_context=context;
}
public responseObject GetData(Service<RequestObject> request)
{
_nullChecker.Check(request)//**;
_validator.Validate(request);
var result = _context.DoSomethingWith(request);
return result;
}
}
Now you can write tests for MyConcreteClass and use mocked implementations of the dependencies, to ensure that the GetData method correctly uses them.
**and I will guess that this can be replaced with a simple if request==null throw new ArgumentNullException() which is cleaner and simpler anyway.
Is there a way to verify that a UnityEngine.Object.Destroy() method is called for a specific GameObject? Since the UnityEngine.Object is no interface I cannot mock it and check for Verifiable(). I am using C#, NUnit and Moq.
For example:
UnityEngine.Object.Destroy(audioSource);
The only thing I found was this How to Mock (with Moq) Unity methods but this is not what I need.
I appreciate any help or further information about this topic!
One thing I also did was that I extract the call from above into the calling interface and verify that this method is called, but this way I only shift the problem to another layer.
public interface IAudioSource
{
void DestroyUnityObject();
}
Then I can call the Unity Destroy method in there.
public void DestroyUnityObject()
{
UnityEngine.Object.Destroy(mAudioSource);
}
And mock the upper method call.
audioSourceMock.Setup(s => s.DestroyUnityObject()).Verifiable();
But as I said, this only puts the problem elsewhere and I can still not verify that the Unity method is called correctly.
With its current state, UnityEngine doesn't support mocking with Moq. This is because Moq (or any other framework based on DynamicProxy1) can't mock member which is not overridable/implementable (in case of interfaces).
Your best bet would be to create a wrapper as you suggested and inject it to classes that would normally use UnityEngine. This way, you can properly unit test those classes. Unfortunatelly, wrapper itself remains untestable (with Moq that is) and nothing can be done here, unless you use different isolation framework which supports static members mocking or use real implementation of UnityEngine (as regular integration test would).
1 I explained bit of details behind this limitation in my blog post - How to mock private method?
I successfully did this using the following system
public interface IUnityComponentDestroyer
{
void Destroy(Component component);
}
public class UnityComponentDestroyer : IUnityComponentDestroyer
{
/// <inheritdoc />
public void Destroy(Component component)
{
if (!Application.isPlaying)
{
Debug.Log($"Destroy called for {component.name} but it's not runtime, so ignoring call.");
return;
}
Object.Destroy(component);
}
}
Then you can call it in code like this:
IUnityComponentDestroyer backingFieldComponentDestroyer;
public IUnityComponentDestroyer ComponentDestroyer
{
get
{
backingFieldComponentDestroyer ??= new UnityComponentDestroyer();
return backingFieldComponentDestroyer;
}
set => backingFieldComponentDestroyer = value;
}
//Then call it with
ComponentDestroyer.Destroy(this);
And use it in a test like this:
IUnityComponentDestroyer fakeDestroyer = Substitute.For<IUnityComponentDestroyer>();
// do stuff
fakeDestroyer.Received().Destroy(Arg.Any<CurveAnimator>());
I'm trying to use PostSharp to implement a security aspect in order to apply method level authorisation checks in my repository layer.
The concept is outlined here.
However these authorisation checks are getting in the way during unit testing, making them more into integration tests.
What would be the best way to isolate these as unit tests, essentially ignoring/mocking the security aspect so that I can just test the actual class behaviour without the need to initialise a bunch of security information?
Does AOP inherently conflict with unit testing?
To answer your 2nd question first, no, AOP doesn’t inherently conflict with unit testing. Usually I’d say it’s best to unit test the methods and the aspects separately.
In your case, there are several options.
The easiest is simply to have the unit test setup method make sure the thread has the required permissions.
If you don’t want to do that, there are two ways you could separate things out for your unit test.
The first is to extract all the code from the methods that you are applying security aspects to into separate methods like this:
[SecurityAspect]
void DoSomething()
{
DoSomethingInternal();
}
void DoSomethingInternal()
{
// this is the real code
}
Then you can run your unit tests against all the unsecured ‘internal’ methods – which tests the logic in them without worrying about security.
The second approach would be to inject a mock permissions tester into the aspect itself. To be able to do this, you would have to define a separate class and interface that does the actual logic of testing the security, something like this (assuming it’s a Thread that you pass in to verify the security):
public interface IPermissionsChecker
{
bool HasPermissions(Thread thread);
}
This is your permissions checker for your live system:
public class RealPermissionsChecker : IPermissionsChecker
{
public bool HasPermissions(Thread thread)
{
// do your real work here
}
}
And this is the one you’ll use in your unit tests
public class MockPermissionsChecker : IPermissionsChecker
{
public bool HasPermissions(Thread thread)
{
return true;
}
}
Now you need to define your aspect something like this:
public class SecurityChecker : OnMethodBoundaryAspect
{
IPermissionsChecker _checker;
public override void OnEntry(MethodExecutionArgs args)
{
if (!_checker.HasPermissions(Thread.CurrentThread))
throw new SecurityException("No permissions");
}
}
The only remaining issue is the need to inject the correct permissions checker into the aspect.
The slightly hacky way I've done this before is to make _checker a static field, and provide a static method to initialize it:
public class SecurityChecker : OnMethodBoundaryAspect
{
private static IPermissionsChecker _checker;
public static void InjectChecker(IPermissionsChecker checker)
{
// best put some code here to make sure this is only called once,
// as well as doing thread synchronization
if (_checker == null)
_checker = checker;
}
The fact that InjectChecker is static means you can access it from your app startup (or unit test startup) code. I suspect unit test purists would frown on this - and you do have to make sure you do call it at app startup, but I think it is the simplest way to inject the checker into the aspect, circumventing the fact that the rest of your code can't directly access instances of the aspect.
The more complicated alternative is to override RunTimeInitialize() in your aspect - this method is called by PostSharp when the aspect is initialized. You'd probably do something like this:
public override void RuntimeInitialize(MethodBase method)
{
base.RuntimeInitialize();
this._checker =PermissionsCheckerProvider.Current.GetChecker();
}
You'll see that requires you to define another class:
public class PermissionsCheckerProvider
{
// make sure you set this at app startup, either to the mock or to the real checker
public static PermissionsCheckerProvider Current { get; set;}
public IPermissionsChecker GetChecker()
{
}
}
This approach guarantees that the method will attempt its initialization at the right time, but then you have the problem of making sure you have supplied an appropriate current provider before the aspect attempts to initialize. So I personally would probably go for the first approach to keep things simple.
There's some discussion about dependency injection and RuntimeInitialize here. https://codereview.stackexchange.com/questions/20341/inject-dependency-into-postsharp-aspect
Two links that extensively answer your question:
Recording of a webinar on the subject, with two different opinions: Matt Groves and myself
Official PostSharp documentation about testing of aspects
If you are using Typemock in your unit tests you can use something like
MyAspect myAspectMock = Isolate.Fake.Instance<MyAspect>(Members.MustSpecifyReturnValues);
Isolate.Swap.AllInstances<MyAspect>().With(myAspectMock);
This allows you to control what tests the aspects are used on, and which ones are not, allowing you to test the method itself, and with the advices applied.
Presumably there would be a similar mechanism with other mocking frameworks