How to test method1 only when it depends on method 2 - c#

Given I have a WCF service with an (example) implementation:
public interface IFoo
{
void Bar();
void Baz();
}
public interface ISomeDependency
{
void DoStuff();
}
public class Foo : IFoo
{
ISomeDependency _someDependency;
public Foo(ISomeDependency someDependency)
{
this._someDependency = someDependency;
}
public void Bar()
{
// Some stuff
_someDependency.DoStuff();
if (1 == 1) // some condition that won't always be true
this.Baz();
}
public void Baz()
{
// some stuff
_someDependency.DoStuff();
}
}
How do I go about unit testing Foo.Bars implementation without caring about the results of Foo.Baz? Specifically, I want to know that Foo.Baz(); was (or wasn't) called depending on how I'm mocking the call to Foo.Bar, but don't necessarily want Foo.Bazs logic to "fire".
I was originally thinking of doing something like this:
public class Foo : IFoo
{
// ... same as previous
public virtual void Baz()
{
// some stuff
_someDependency.DoStuff();
}
}
and then in my unit testing project having:
public class TestFoo : Foo
{
public bool IsBazFired { get; private set; }
public TestFoo(ISomeDependency someDependency)
: base (someDependency)
{
IsBazFired = false;
}
public override void Baz()
{
IsBazFired = true;
}
}
This way I can see that Foo.Baz fired in my testing (though I would have to test with TestFoo rather than Foo. Is there another way I can go about doing this? It seems like little enough work right now, but if trying to implement this all over the place, the code could/would become littered with test implementations of classes.
I don't necessarily like marking my function as virtual just so i can stub out an implementation for testing... so I'm hoping there another way.
I'm currently just starting out with the mocking framework Moq, if that makes a difference on how to go about accomplishing my desired results.

Here's how I went about accomplishing the tests with Moq.
First, mark methods that need to be "stubbed" out as virtual (hopefully this is not considered bad practice):
public virtual void Baz()
{
// some stuff
_someDependency.DoStuff();
}
In your test, you can set up a mock object of a class, rather than an interface. Up until this point, I was only mocking interfaces:
[TestClass]
public class FooTests
{
Mock<Foo> _mockFoo;
Mock<ISomeDependency> _mockSomeDependency;
[TestInitialize]
public void Setup()
{
_mockSomeDependency = new Mock<ISomeDependency>();
_mockFoo = new Mock<Foo>(_mockSomeDependency.Object);
}
[TestMethod]
public void Testing_BazIsNotCalled()
{
_mockFoo.CallBase = true;
_mockFoo.Setup(s => s.Baz());
_mockFoo.Object.Bar();
_mockFoo.Verify(v => v.Baz(), Times.Never);
}
[TestMethod]
public void Testing_BazIsCalled()
{
_mockFoo.CallBase = true;
_mockFoo.Setup(s => s.Baz());
_mockFoo.Object.Bar();
_mockFoo.Verify(v => v.Baz(), Times.Once);
}
}
using CallBase = true on my mock signifies that anything not explicitly mocked will use the classes implementation.
In my _mockFoo.Setup(s => s.Baz()); I am overriding the "base" functionality of Baz() and providing a new implementation (in this case a stub). Then I am actually invoking the base Bar(), and testing with _mockFoo.Verify(...); whether or not the Baz() call proceeded. This verify check is of course based on if (1==1) which in this case would always be true, but I just wanted to get some "fake logic" in there so I would have a block to check against.
Note that if you forget to mark your method attempting to be stubbed as virtual, your code will compile fine, but you'll encounter an exception during run time similar to:
Result StackTrace:
...
at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo method)
at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b()
at Moq.PexProtector.Invoke[T](Func`1 function)
at Moq.Mock.Setup[T,TResult](Mock`1 mock, Expression`1 expression, Condition condition)
at Moq.Mock`1.Setup[TResult](Expression`1 expression)
at FooTests.Testing_BazIsNotCalled() in UnitTests.cs:line 23
Result Message: Initialization method Testing_BazIsNotCalled threw exception. System.NotSupportedException: System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: s => s.Baz()).
I don't know if I'm using the correct terms for the above (stubs/mocks), but it's working nonetheless.

Related

How to make a specific order for calling methods?

For example, I have a class with interface, which has few methods.
What is the best way to call methods always only in a specific order in the class?
public class SomeClass
{
void Start(ISomeInterface testClass)
{
testClass.Method1();
testClass.Method2();
testClass.Method3();
}
}
public interface ISomeInterface
{
void Method1();//should run 2nd
void Method2();// 1st
void Method3();// 3rd
}
Take a look at Template Method Design Pattern
The intent of Template Method Design Pattern is to define the skeleton of an algorithm in an operation, deferring some
steps to client subclasses. Template Method lets subclasses redefine
certain steps of an algorithm without changing the algorithm's
structure.
abstract class SomeClass : ISomeInterface
{
public abstract void Method1();
public abstract void Method2();
public abstract void Method3();
// The template method
public void Start()
{
testClass.Method1();
testClass.Method2();
testClass.Method3();
}
}
class ImplementationClass : SomeClass
{
public override void Method1()
{
...
}
public override void Method2()
{
...
}
public override void Method3()
{
...
}
}
// Usage
var implementationClass = new ImplementationClass();
implementationClass.Start();
It's normal to write code so that methods are expected to run in certain order. But in that case we wouldn't want to just expose all of the methods and expect the caller to just "know" to run them in a certain order. If something is required then we must somehow enforce it.
If the methods of an interface can be executed in any order but in one specific case we want to run them in a particular order, that's easy. We just do them in the order we want:
testClass.Method2();
testClass.Method1();
testClass.Method3();
If methods must always be executed in a particular order then it doesn't make sense to expose an interface that allows us to execute them in just any order. The interface should describe how we want the class to be used. In that case this would make more sense:
public interface IDoesSomething
{
void DoSomething();
}
public class DoesSomething : IDoesSomething
{
public void DoSomething()
{
DoAnotherThing();
DoOneThing();
SomethingElse();
}
private void DoOneThing(){}
private void DoAnotherThing(){}
private void SomethingElse(){}
}
Now the interface tells other classes how to interact with it, but the details of how that gets done, which includes a particular sequence of steps, is encapsulated (hidden) inside the implementation of that class.
We're still doing the same thing - breaking a process into steps - but choosing how much of it we expose outside the class. We're making it easier to use our class correctly by making it impossible to use it incorrectly.
As far as I see, Template methodis not what you are looking for. (Unless you are one of those unpleasant people using answers without accepting ones ;))
If you'd like to give an illusion of freedom to a user and to punish one for using it wrong way, it could be done the following way.
Define an attribute:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class OrderAttribute : Attribute
{
public int Order { get; }
public OrderAttribute(int order) => Order = order;
}
Then define an interface:
public interface IObeyOrder
{
[Order(2)]
[Order(4)]
void Method1(); // should run 2nd or 4th
[Order(1)]
void Method2(); // 1st
[Order(3)]
void Method3(); // 3rd
void Method4(); // order doesn't matter
}
And implement it on a class, calling CheckOrder() first in each method:
public partial class ObeyOrder : IObeyOrder
{
public void Method1()
{
CheckOrder();
Console.WriteLine("Method1");
}
public void Method2()
{
CheckOrder();
Console.WriteLine("Method2");
}
public void Method3()
{
CheckOrder();
Console.WriteLine("Method3");
}
public void Method4()
{
CheckOrder();
Console.WriteLine("Method4");
}
public void Method5() // non-interface
{
CheckOrder();
Console.WriteLine("Method5");
}
}
where CheckOrder() is:
public partial class ObeyOrder : IObeyOrder
{
private static readonly Dictionary<string, int[]> orderedMethods = OrderHelper<IObeyOrder>.OrderedMethods;
private readonly Queue<int> orders = new Queue<int>(orderedMethods.Values.SelectMany(i => i).OrderBy(i => i));
private void CheckOrder([CallerMemberName] string methodName = "")
{
if (!orderedMethods.TryGetValue(methodName, out var methodOrders))
return;
var order = orders.Peek();
if (!methodOrders.Contains(order))
throw new Exception($"Wrong method call order. Method '{methodName}' with orders [{string.Join(", ", methodOrders)}]. Expected order {order}.");
orders.Enqueue(orders.Dequeue());
}
}
Of course, you can do it in a non-partial class.
public static class OrderHelper<T>
{
public static Dictionary<string, int[]> OrderedMethods { get; } = typeof(T)
.GetMethods()
.Select(method => new
{
Method = method.Name,
Orders = method.GetCustomAttributes(typeof(OrderAttribute), false)
.Cast<OrderAttribute>()
.Select(attribute => attribute.Order)
.ToArray()
})
.Where(method => method.Orders.Length > 0)
.ToDictionary(method => method.Method, method => method.Orders);
}
Usage:
var obeyOrder = new ObeyOrder();
obeyOrder.Method2(); // should go 1st
obeyOrder.Method4(); // can go whenever, since there is no order attribute
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method5(); // can go whenever, since it's non-interface
obeyOrder.Method3(); // should go 3rd
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method2(); // should go 1st (after the last had been already called)
works fine, but
var obeyOrder = new ObeyOrder();
obeyOrder.Method2(); // should go 1st
obeyOrder.Method4(); // can go whenever, since there is no order attribute
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method5(); // can go whenever, since it's non-interface
obeyOrder.Method3(); // should go 3rd
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method2(); // should go 1st (after the last had been already called)
obeyOrder.Method2(); // should throw since the 2nd (obeyOrder.Method1()) is expected
throws
Wrong method call order. Method 'Method2' with orders [1]. Expected order 2.
First of all i think you got some concepts mixed up, a class implements an interface, you cannot have an interface class. What you do by implementing an interface is ensure that the consumer class of the interface has to implement that method signature in his code.
Secondly, there is no way to execute methods in a certain order if they re in an interface, this is because interface methods (not the code itself from each method, an interface does NOT HAVE ANY LOGIC on it). Probably what you are looking for here is class (can be abstract not sure why do you need an interface though), and you could have this 3 methods as private members of it and have a public method that executes the 3 of them. Like this:
public class Example
{
private void MethodA()
{
//logic from methodA
}
private void MethodB()
{
//logic from methodB
}
private void MethodC()
{
//logic from methodC
}
public void MethodA()
{
MethodB();
MethodA();
MethodC();
}
}
Only expose the callable methods in an interface, and return a new interface when the method has been called.
interface IMethod1 {
IMethod2 Method1();
}
interface IMethod2 {
IMethod3 Method2();
}
Initially, you return a IMethod1. This only exposes Method1(), so it's not possible to call Method2 out of order. When calling Method1(), it returns an IMethod2 that exposes Method2(), so that can be called.
These interfaces can be implemented by the same class, which exposes only some methods at a time through the various interfaces.
Edit: I wrote a blog post about this: Enforcing object lifecycles through interfaces

Protected virtual method of a mocked abstract class is not called

I am mocking an abstract class with NSubstitute and expect its protected virtual method to be called.
public abstract class A
{
protected virtual bool ProtectedMethod()
{
return true;
}
public bool PublicMethod()
{
return ProtectedMethod();
}
}
public class ATest
{
[Fact]
public void Test()
{
var anA = Substitute.For<A>();
var result = anA.PublicMethod();
Assert.True(result);
}
}
This test fails when executed. In fact, it fails even if the class is not abstract. If this is normal behavior, what should I do to ensure the ProtectedMethod is called?
PS. If the method is not virtual, it works as expected.
As pointed out in the comments, be careful substituting for classes. I recommend installing the NSubstitute.Analyzers to pick up issues with class substitutes at compile time.
The reason this test is failing is because you are substituting for A, so NSubstitute replaces all virtual implementations with substitute ones (which generally return default unless otherwise stubbed out, in this case false).
You can use a partial substitute which will maintain the existing implementation by default (i.e. ProtectedMethod will keep returning true as per the base implementation):
[Fact]
public void TestUsingPartialSub() {
var anA = Substitute.ForPartsOf<A>();
var result = anA.PublicMethod();
Assert.True(result);
}
"... what should I do to ensure the ProtectedMethod is called?"
NSubstitute can not assert on protected methods (it works via the publicly accessible API). If possible, you can refactor the code to use a strategy pattern to inject the protected behaviour. This will make the code more flexible (including the flexibility to inject different behaviour for testing), at the cost of a slightly more complex design.
public interface IProtectedMethod {
bool ProtectedMethod();
}
public class AA {
private readonly IProtectedMethod x;
public AA(IProtectedMethod x) {
this.x = x;
}
public bool PublicMethod() {
return x.ProtectedMethod();
}
}
public class AATest {
[Fact]
public void TestUsingStrategySub() {
var x = Substitute.For<IProtectedMethod>();
var anA = new AA(x);
anA.PublicMethod();
x.Received().ProtectedMethod();
}
}
(Please excuse the naming in this example, I've tried to keep it similar to the original to make it clearer where the various bits of logic have moved.)

How to test a virtual method defined in an abstract class?

I need to unit-test a virtual method defined in an abstract class. But the base class is abstract, so I can't create an instance of it. What do you recommend me to do?
This is a follow up to the following question: I am thinking about if it is possible to test via an instance of a subclass of the abstract class. Is it a good way? How can I do it?
There's no rule that says a unit test can't define its own classes. This is a fairly common practice (at least for me anyway).
Consider the structure of a standard unit test:
public void TestMethod()
{
// arrange
// act
// assert
}
That "arrange" step can include any reasonable actions (without side-effects outside of the test) which set up what you're trying to test. This can just as easily include creating an instance of a class whose sole purpose is to run the test. For example, something like this:
private class TestSubClass : YourAbstractBase { }
public void TestMethod()
{
// arrange
var testObj = new TestSubClass();
// act
var result = testObj.YourVirtualMethod();
// assert
Assert.AreEqual(123, result);
}
I'm not sure what your abstract class looks like, but if you have something like:
public abstract class SomeClass
{
public abstract bool SomeMethod();
public abstract int SomeOtherMethod();
public virtual int MethodYouWantToTest()
{
// Method body
}
}
And then, as #David suggested in the comments:
public class Test : SomeClass
{
// You don't care about this method - this is just there to make it compile
public override bool SomeMethod()
{
throw new NotImplementedException();
}
// You don't care about this method either
public override int SomeOtherMethod()
{
throw new NotImplementedException();
}
// Do nothing to MethodYouWantToTest
}
Then you just instantiate Test for your unit test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
SomeClass test = new Test();
// Insert whatever value you expect here
Assert.AreEqual(10, test.MethodYouWantToTest());
}
}

C# Unit Testing (Xunit and Moq) - Test an interface and its implementations separately

I want to separate the unit tests for testing the interface behavior itself and the additional business behavior of the implementations.
public interface IIncrementor
{
void Increment();
int Count { get; }
}
public class AIncrementor : IIncrementor { /* Implementation */ }
public class BIncrementor : IIncrementor { /* Implementation */ }
To ensure the correctness of the business behavior of an interface I need to check all according implementations against my defined unit tests. Of course every implementation has its own additional behavior to test, but I don't want to repeat myself over and over again.
My current solution was to create an abstract test-class with an abstract property for the subclasses to implement.
public abstract class IIncrementorTest
{
protected abstract IIncrementor Incrementor { get; }
[Fact]
public void WhenIncremented_ThenCounterHasCorrectValue()
{
var oldCount = Incrementor.Count;
Incrementor.Increment();
Assert.Equal(oldCount + 1, Incrementor.Count);
}
}
public class AIncremetorTest : IIncrementorTest
{
protected override IIncrementor Incrementor => new AIncrementor();
[Fact]
public void WhenSomeAdditional_ThenCheckSomething() { /* More test */ }
}
public class BIncremetorTest : IIncrementorTest
{
protected override IIncrementor Incrementor => new BIncrementor();
[Fact]
public void WhenSomeAdditional_ThenCheckSomething() { /* More test */ }
}
But that leads to some problems, e.g. when a test case needs to build an instance differently which is very likely to happen. Would you suggest to create abstract properties for these cases?
protected abstract IIncrementor IncrementorForCheckingSomething { get; }
Or is there a best practice approach which solves this interface-test problem comprehensively?
If I'm understanding correctly, you want to write one set of tests for your interface, and apply those tests to any classes which implement that interface.
You could use reflection to find all the types in your assembly which implement the interface with something like this:
var interfaceType = typeof(IIncrementor);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => t.IsClass && interfaceType.IsAssignableFrom(t));
and instantiate all of those types. This could be tricky if they don't share a common constructor signature; but would work for the examples in the question using the default constructor...
foreach(Type t in types)
{
yield return (IIncrementor)Activator.CreateInstance(t,null);
}
Put that code in a method with return type IEnumerable<IIncrementor> and give that method the attribute MemberData to pass these instances into each of the tests.

moq only one method in a class

I'm using moq.dll
When I mock a class(all the IRepository interface) i use this line code
int state = 5;
var rep = new Mock<IRepository>();
rep.Setup(x => x.SaveState(state)).Returns(true);
IRepository repository = rep.Object;
but in this case i mock all the function in repository class.
Then all the methods in class repository are substituted with the methods setup of Mock dll
I want use all the methods defined in class repository(the real class) and mock only one function(SaveState)
How can I do this? Is possible?
You can create an instance of the real repository, then use the As<>() to obtain the desired interface, which you can then override with the setup, like this:
var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
.As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Then mockRep.Object as the repository dependency to the class under test.
Note that you will only be able to Mock methods on the Interface*, or virtual methods, in this way.
Update : *This might not work in all scenarios, since .Setup will only work on virtual methods, and C# interface implementations are "virtual" and sealed by default. And using As() will prevent the partial mock behaviour.
So it appears that the RealRepository concrete class will need to implement the IRepository interface with virtual methods in order for the partial mock to succeed, in which case CallBase can be used for the wire-up.
public interface IRepo
{
string Foo();
string Bar();
}
public class RealRepo : IRepo
{
public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
// ** These need to be virtual in order for the partial mock Setups
public virtual string Foo() { return "RealFoo"; }
public virtual string Bar() {return "RealBar"; }
}
public class Sut
{
private readonly IRepo _repo;
public Sut(IRepo repo) { _repo = repo; }
public void DoFooBar()
{
Console.WriteLine(_repo.Foo());
Console.WriteLine(_repo.Bar());
}
}
[TestFixture]
public class SomeFixture
{
[Test]
public void SomeTest()
{
var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
// For the partially mocked methods
mockRepo.Setup(mr => mr.Foo())
.Returns("MockedFoo");
// To wireup the concrete class.
mockRepo.CallBase = true;
var sut = new Sut(mockRepo.Object);
sut.DoFooBar();
}
}
I came to this page because I had exactly the same problem: I needed to mock a single method, which was relying on many external sources and could produce one of three outputs, while letting the rest of the class do its work. Unfortunately the partial mock approach proposed above did not work. I really don't know why it did not work. However, the main problem is that you can't debug inside such mocked class even if you put break points where you want. This is not good because you might really need to debug something.
So, I used a much simpler solution: Declare all methods that you want to mock as virtual. Then inherit from that class and write one-liner mock overrides to return what you want, for example:
public class Repository
{
/// <summary>
/// Let's say that SaveState can return true / false OR throw some exception.
/// </summary>
public virtual bool SaveState(int state)
{
// Do some complicated stuff that you don't care about but want to mock.
var result = false;
return result;
}
public void DoSomething()
{
// Do something useful here and assign a state.
var state = 0;
var result = SaveState(state);
// Do something useful with the result here.
}
}
public class MockedRepositoryWithReturnFalse : Repository
{
public override bool SaveState(int state) => false;
}
public class MockedRepositoryWithReturnTrue : Repository
{
public override bool SaveState(int state) => true;
}
public class MockedRepositoryWithThrow : Repository
{
public override bool SaveState(int state) =>
throw new InvalidOperationException("Some invalid operation...");
}
That's all. You can then use your mocked repos during unit tests AND you can debug anything you need. You can even leave the protection level below public so that not to expose what you don't want to expose.

Categories