For testing purposes I want to run the real implementation of a class but see the functions that where called on it after its execution. If I understood that documentation correctly that is what the ForPartsOf is for. However after using it, it never returns any used calls (while I know they get triggered by breakpoints).
I created a small program to reflect my problem, at the end I would expect the console output to tell me both instances received 2 calls. but the 'real' one returns 0.
test interface:
public interface ITestClass
{
string DoSomething();
}
test class:
public class TestClass : ITestClass
{
private readonly string mOutput;
public TestClass(string output)
{
mOutput = output;
}
public string DoSomething()
{
return mOutput;
}
}
test program:
//using NSubstitute;
//using System;
//using System.Linq;
private const int cItterations = 2;
public void Run()
{
ITestClass mock = Substitute.For<ITestClass>();
mock.DoSomething().Returns("fake");
ITestClass real = Substitute.ForPartsOf<TestClass>("real");
RunCalls(mock); //fake, fake
Console.WriteLine();
RunCalls(real); //real, real
Console.WriteLine();
Console.WriteLine($"mock calls: {mock.ReceivedCalls().Count()}"); //mock calls: 2
Console.WriteLine($"real calls: {real.ReceivedCalls().Count()}"); //real calls: 0 (expected 2?)
}
private void RunCalls(ITestClass implementation)
{
for (int i = 0; i < cItterations; i++)
{
Console.WriteLine(implementation.DoSomething());
}
}
I'm most likely doing something wrong but I can't seem to figure out what it is. Any help would be appreciated.
using:
ms .net 4.7.2 with NSubstitute 4.0.0 (via nuget)
NSubstitute cannot intercept non-virtual class members. (For an explanation as to why, please see the non-virtual members section of the How NSubstitute works documentation.)
Try it with DoSomething declared as a virtual member:
public class TestClass : ITestClass
{
// ... other members elided ...
public virtual string DoSomething()
{
return mOutput;
}
}
Adding the NSubstitute.Analyzers package to your test projects will pick up cases where non-virtual members are used with NSubstitute.
Related
I have a method
using Microsoft.VisualStudio.TestTools.UnitTesting; // using visual studio's test framework
[TestMethod]
public void ATestMethod()
{
// stuff
}
from a public class ATestClass. This test class runs two types of tests :
tests requiring that a certain software is installed on the machine running the test
tests that can run free
To handle this, I added a public class BaseTestClass from which I made ATestClass derive, and in ATestClass I added a :
public bool isTheSoftwareInstalledOnTheMachine()
{
// stuff
}
and I "decorated" all internal scopes of tests from ATestClass as follows :
[TestMethod]
public void ATestMethod()
{
if (isTheSoftwareInstalledOnTheMachine())
{
// stuff
}
}
I find this horrible. I would rather like to be able to write something like :
[TestMethod]
[RunIfTheSoftwareInstalledOnTheMachine]
public void ATestMethod()
{
// stuff
}
but I don't know if one is allowed to define "custom" [characterizer]'s. (I don't even know the right word for them.) If it is, would that be the best design ? (I heard about the decorator pattern, but I don't know if I could make it generic enough in my context, because I would potentially need to use the condition for many other test classes.) Anyway, how would I proceed with characterizer's ?
I know you're using VS test framework but if you can change to NUnit you can accomplish what you want.
Test case:
using NUnit.Framework;
[TestFixture]
public class MyAppTests
{
[Test]
[RunIfTheSoftwareInstalledOnTheMachine]
public void ATestMethod()
{
// Executes if custom attribute is true, otherwise test case is ignored
}
}
Custom attribute:
using NUnit.Framework;
using NUnit.Framework.Interfaces;
public class TestHelper
{
public static bool IsTheSoftwareInstalledOnTheMachine()
{
// Return state of software
return true;
}
}
public class RunIfTheSoftwareInstalledOnTheMachineAttribute : Attribute, ITestAction
{
public ActionTargets Targets { get; private set; }
public void AfterTest(ITest test) {}
public void BeforeTest(ITest test)
{
if (!TestHelper.IsTheSoftwareInstalledOnTheMachine())
{
Assert.Ignore("Omitting {0}. Software is not installed on machine.", test.Name);
}
}
}
If you define your own attribute you surerly have to check for its existance on your own. You can´t expect your framework to guess what the attribute is for.
But I suppose you don´t even need an attribute to do this. You can simply ignore the test by putting the logic inside the test-method anyway:
[Test]
public void MyTest()
{
if(!RunIfTheSoftwareInstalledOnTheMachine)
Assert.Ignore("Test not run because no software was installed");
// your actual test-code
}
Another approach is to use the CategoryAttribute provided by NUnit, with which you can run only those tests that fall within your provided category:
[Test]
[Category("SoftwareInstalled")]
public void MyTest() { /* ... */ }
EDIT: You could also use the TestCaseAttribute with a specific method that returns a TestCase when the condition is met:
[TestCaseSource("ProvideTestcases")]
public void MyTest() { /* ... */ }
private static IEnumerable<TestCaseData> ProvideTestcases()
{
if(RunIfTheSoftwareInstalledOnTheMachine)
yield return new TestCaseData();
}
If the codition is not met no testcase is generated at all.
If the software being installed on the machine is a requirement for any of the tests to pass and any one test failing means the whole suite fails then why bother checking in multiple tests if the software is installed? Just write a single test to fail if the software is not installed and throw a useful exception. Something like:
[Test]
public void EnsureImportantSoftwareIsInstalled()
{
if(!importantSoftwareIsInstalled)
{
Assert.Fail($"Software X must be installed for the tests in {nameof(MyTestClass)} to run, please install it");
}
}
For Nunit 2.6, a slight variation of the HimBromBeere's answer works well for me. The test case is displayed as ignored.
[TestCaseSource("ProvideTestcases")]
public void MyTest() { /* ... */ }
private static IEnumerable<TestCaseData> ProvideTestcases()
{
if(RunIfTheSoftwareInstalledOnTheMachine)
yield return new TestCaseData().Ignore();
}
I am executing unit test for one of class method "Execute", but don't want to execute class constructor code.
Is there any way to skip constructor code call from the unit test execution?
Class Code,
public class DemoCls
{
public DemoCls()
{
string ConfigFolderPath = Path.Combine(Environment.CurrentDirectory, #"\Config");
//string dataFolder = #"C:\Data1";
foreach (string X in Directory.EnumerateFiles(ConfigFolderPath, "test" + "*.xml"))
{
}
}
public void Execute()
{
}
}
Unit Test Code,
[TestClass()]
public class DemoClsTests
{
[TestMethod()]
public void ExecuteTest()
{
var X = new DemoCls();
X.Execute();
}
}
Rewrite the class, one of two ways:
Pass the information into the constructor using an interface (which can be mocked in unit-tests)
public interface IConfigFiles
{
List<string> Files { get; set; }
}
public DemoCls(IConfigFiles files)
{
}
Remove configuration code from the constructor, and put it in a different function instead.
public DemoCls()
{
// does nothing
}
public void Setup()
{
string ConfigFolderPath = Path.Combine(Environment.CurrentDirectory, #"\Config");
//...
}
Interfaces are better for unit-testing.
"Is there any way to skip constructor code call from the unit test execution?"
The answer is: No (for instance methods)
You can use a unit testing frameworks that allows you to mock concrete classes in order to fake a class without an interface, for example i'm using Typemock Isolator and with that i can mock almost any class and decide what is happening with all the class's members and its constructor.
here is a test for the class that you had in your question:
[TestMethod,Isolated]
public void TestMethod()
{
var fake = Isolate.Fake.Instance<DemoCls>(Members.CallOriginal, ConstructorWillBe.Ignored);
fake.Execute();
Isolate.Verify.WasCalledWithAnyArguments(() => fake.Execute());
}
You could wrap you ctor code in the "if" preprocessor directive and execute it conditionally, only during a non-test run.
#define DEBUG
// ...
#if DEBUG
Console.WriteLine("Debug version");
#endif
See
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if
I have a base class:
public abstract class MyBaseClass
{
protected virtual void Method1()
{
}
}
and a derived class:
public class MyDerivedClass : MyBaseClass
{
public void Method2()
{
base.Method1();
}
}
I want to write a unit test for Method2 to verify that it calls Method1 on the base class. I'm using Moq as my mocking library. Is this possible?
I came across a related SO link:
Mocking a base class method call with Moq
in which the 2nd answer suggests it can be achieved by setting CallBase property to true on the mock object. However it's not clear how this would enable the call to the base class method (Method1 in the above example) to be verified.
Appreciate any assistance with this.
Unit tests should verify behavior, not implementation. There are several reasons for this:
The results are the goal, not how you get the results
Testing results allows you to improve the implementation without re-writing your tests
Implementations are harder to mock
You might be able to put in hooks or create mocks that verify that the base method was called, but do you really care how the answer was achieved, or do you care that the answer is right?
If the particular implementation you require has side effects that you can verify, then that is what you should be validating.
Mocking the base class from the perspective of the derived class is not possible. In your simple example, I would suggest one of the two options.
Option 1: In the event that MyDerivedClass really shouldn't care what MyBaseClass is up to, then use dependency injection! Yay abstraction!
public class MyClass
{
private readonly IUsedToBeBaseClass myDependency;
public MyClass(IUsedToBeBaseClass myDependency){
_myDependency = myDependency;
}
public void Method2()
{
_myDependency.Method1();
}
}
Elsewhere in test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var dependency = new Mock<IUsedToBeBaseClass>();
var unitUnderTest = new MyClass(dependency.Object);
var unitUnderTest.Method2();
dependency.Verify(x => x.Method1(), Times.Once);
}
}
Option 2: In the event that MyDerivedClass NEEDS to know what MyBaseClass is doing, then test that MyBaseClass is doing the right thing.
In alternative test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var unitUnderTest = new MyDerivedClass();
var unitUnderTest.Method2();
/* verify base class behavior #1 inside Method1() */
/* verify base class behavior #2 inside Method1() */
/* ... */
}
}
What you're describing is not a test of your code, but a test of the behavior of the language. That's fine, because it's a good way to ensure that the language behaves the way we think it does. I used to write lots of little console apps when I was learning. I wish I'd known about unit testing then because it's a better way to go about it.
But once you've tested it and confirmed that the language behaves the way you expect, I wouldn't keep writing tests for that. You can just test the behavior of your code.
Here's a real simple example:
public class TheBaseClass
{
public readonly List<string> Output = new List<string>();
public virtual void WriteToOutput()
{
Output.Add("TheBaseClass");
}
}
public class TheDerivedClass : TheBaseClass
{
public override void WriteToOutput()
{
Output.Add("TheDerivedClass");
base.WriteToOutput();
}
}
Unit test
[TestMethod]
public void EnsureDerivedClassCallsBaseClass()
{
var testSubject = new TheDerivedClass();
testSubject.WriteToOutput();
Assert.IsTrue(testSubject.Output.Contains("TheBaseClass"));
}
Ok, this may get lengthy. I am trying to do two things:
I want to have a class that implements an interface by holding an instance of another class that every call is routed to.
I also want to intercept all method calls and do something.
Doing both on their own works great. Combining them seems to work only in one execution order and as Murphy has it, it's the wrong one (at least for me).
I'd like to inject the composition first so that the interception of all calls will also intercept those that were previously injected.
namespace ConsoleApplication13
{
using System;
using System.Reflection;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Dependencies;
using PostSharp.Extensibility;
[Serializable]
[ProvideAspectRole("COMPOSER")]
public sealed class ComposeAspectAttribute : CompositionAspect
{
[NonSerialized]
private readonly Type interfaceType;
private readonly Type implementationType;
public ComposeAspectAttribute(Type interfaceType, Type implementationType)
{
this.interfaceType = interfaceType;
this.implementationType = implementationType;
}
// Invoked at build time. We return the interface we want to implement.
protected override Type[] GetPublicInterfaces(Type targetType)
{
return new[] { this.interfaceType };
}
// Invoked at run time.
public override object CreateImplementationObject(AdviceArgs args)
{
return Activator.CreateInstance(this.implementationType);
}
}
[Serializable]
[ProvideAspectRole("INTERCEPTOR")]
[MulticastAttributeUsage(MulticastTargets.Method)]
[AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, "COMPOSER")]
public sealed class InterceptAspectAttribute : MethodInterceptionAspect
{
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
base.CompileTimeInitialize(method, aspectInfo);
// Warning in VS output
Message.Write(method, SeverityType.Warning, "XXX", "Method: " + method.Name);
}
public override void OnInvoke(MethodInterceptionArgs args)
{
Console.WriteLine("Intercepted before");
args.Proceed();
Console.WriteLine("Intercepted after");
}
}
interface ITest
{
void Call();
}
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
[InterceptAspect(AspectPriority = 1)]
[ComposeAspect(typeof(ITest), typeof(TestImpl), AspectPriority = 2)]
class Test
{
// this should, after compilation, have all methods of ITest, implemented through an instance of TestImpl, which get intercepted before TestImpl is called
public void CallLocalImplementedTest()
{
Console.WriteLine("CALL local implemented");
}
}
class Program
{
static void Main()
{
var test = new Test();
ITest t = Post.Cast<Test, ITest>(test);
Console.WriteLine("TEST #1");
t.Call();
Console.WriteLine("TEST #2");
test.CallLocalImplementedTest();
Console.ReadLine();
}
}
}
I have tried to influence the execution order of the two aspects by
AspectRoleDependency, making the interceptor depend on the composer to run first
AspectPriority, also making the composer run first.
As the tests always yield
TEST #1
CALL remote implemented
TEST #2
Intercepted before
CALL local implemented
Intercepted after
it obviously doesn't work. Do you have a clue why my execution order has not changed? Did I do something wrong, did I miss a detail in the documentation? What can I do to intercept my composition-injected methods as well?
With the current aspects and your current setup you cannot achive your desired result.
The problem is in how Postsharp work: it does the IL waving in one step and it only applies the InterceptAspect to the methods which are present at original compile time so it does not see the new interface implementations added with the ComposeAspect.
So no ordering of the accepts or providing roles, priorities or other configuration would help here.
One workaround would be to add the InterceptAspect on the injected TestImpl class:
[InterceptAspect]
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
In this case the logging logic will be added directly TestImpl so these method will contain the logging when it will be composed into your Test class.
Or if you don't mark every implementation you can put your aspect on the interface itself with:
[InterceptAspect(AttributeInheritance = MulticastInheritance.Multicast)]
interface ITest
{
void Call();
}
I'm a big fan of the xUnit.NET framework; I find it light, simple, clean, and extensible.
Now let's say that I have a class like so:
public class AdditionSpecification
{
static int result;
public void Because()
{
result = 2 + 2;
}
public void Result_is_non_zero()
{
Assert.True(result <> 0);
}
public void Result_is_correct()
{
Assert.Equal(4, result);
}
}
With the test class above I want xUnit.NET to see 2 test cases and to run the Because() method before each of them.
Leaving aside any issues you may have with my class or method names, the structure of this test/specification, the xUnit.NET framework, or BDD, here's my question:
How can I tell xUnit.NET that I want to customize how it identifies and executes test methods out of this class without using a custom [Fact]-like attribute on each target test method?
I know that I can derive from BeforeAfterAttribute to decorate each test method with custom before and after execution. How can i do this at the class level? Do i have to write a custom runner?
xUnit.net's IUseFixture allows you to do per fixture setup. You could therefore define your own fixture class:
public class AdditionFixture : IDisposable
{
public int Because()
{
return 2 + 2;
}
public void Dispose()
{
//test tear down code
}
}
Your test class can then implement this (with setFixture requiring implementing) :
public class AdditionSpecification : IUseFixture<AdditionFixture>
{
int result;
public void SetFixture(AdditionFixture Fixture)
{
result = Fixture.Because();
}
[Fact]
public void Result_is_non_zero()
{
Assert.True(result <> 0);
}
[Fact]
public void Result_is_correct()
{
Assert.Equal(4, result);
}
}
The xUnit runner will create a single instance of your fixture, and pass it into SetFixture before running each test. After running all of your tests, the runner will then dispose of the fixture if it implements IDisposable. I hope that helps!
The xUnit wiki on codeplex has more information, including a nice example of how to implement IUseFixture to manage a database connection for you test fixtures.
So it turns out that I was looking for the ITestClassCommand.EnumerateTestMethods() method.
The default xUnit.NET test runner
will iterate over all the classes in
your test assembly.
For each one it will check for a RunWithAttribute;
that's your chance to override the
ITestClassCommand implementation
that is used to identify methods
containing tests. (RunWithNUnit is a good example)
ITestClassCommand.EnumerateTestMethods() is called to process the test class and return an IEnumerable of test methods.
each test IMethodInfo is then passed to ITestClassCommand.EnumerateTestCommands(IMethodInfo testMethod) to get the IEnumerable of ITestCommands
each ITestCommand is then executed and given the opportunity to return a result.
In the case of my example above, I would need something like:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RunWithMyTestClassCommandAttribute : RunWithAttribute
{
public RunWithMyTestClassCommandAttribute()
: base(typeof(MyTestClassCommand)) {}
}
Then I could decorate my above example with:
[RunWithMyTestClassCommand]
public class AdditionSpecification
{
static int result;
public void Because()
{
result = 2 + 2;
}
public void Result_is_non_zero()
{
Assert.True(result <> 0);
}
public void Result_is_correct()
{
Assert.Equal(4, result);
}
}
Finally, in MyTestClassCommand, I get to opportunity between EnumerateTestMethods() and EnumerateTestCommands(IMethodInfo testMethod) to use whatever logic I want to locate and construct ITestCommand instances that get executed as individual tests.
BTW, in the process of researching this issue, I ran into a small bug in the xUnit.NET framework where a custom IMethodInfo generated by EnumerateTestMethods() never showed up in EnumerateTestCommands(..) because it was being unwrapped and rewrapped by the test runner or one of it's factories.
I submitted this issue to the xUnit project on codeplex and it was corrected on May 30th, 2009 for xUnit.NET 1.5 CTP 2