c# mock return base method - c#

I am writing a unit test case with NUnit framework to test our code.
The code has referenced to 3rd party libraries like below:
class MyClass: BaseClass
{
public void override FunctionA()
{
var a = BaseFunctionB();
}
}
we don't have sourcecode for BaseClass, but the BaseFunctionB is non-virtual.
I was trying to
Setup(x=> x.BaseFunctionB()).Reteruns("my values");
but it doesn't allow.
I just want to test the FunctionA in MyClass, I don't care whether it's correct in BasefunctionB.
How to test in this case?
----------------------------2018-01-03 updated---------------------------------
I made some update for the BaseClass:
public abstract class BaseClass1//we dont have source code for this class
{
public int GetValue()
{
//do something here
return 1;//
}
public abstract int GenerateOutPut();
}
class abstract class BaseClass2: BaseClass1
{
public new virtual int GetValue()
{
return base.GetValue();
}
}
class MyClass1: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
a += 1;
return a;
}
}
class MyClass2: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
a -= 1;
return a;
}
}
// there are many MyClass
class MyClassN: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
//different logic here.
return a;
}
}
i made a class for testing MyClass1 like below:
class TestClass1: MyClass1
{
public override int GetValue()
{
return 100;
}
}
test case as below:
public void TestFunction()
{
var test = new TestClass1();
var result = test.GetValue();
assert.AreEqual(101, result);
}
Now I have to create many TestClas which looks not good. but in terms of running out code coverage, i have to make it( i try to use mock object to execute, there is no code covered in report, i guess because it create proxy and run it on proxy, so i create the same thing myself to test the original source code)
Do i have a better solution?

Creating the second base class and the new member to encapsulate the 3rd party dependency was a good idea. It allows you to override the member in derived classes. In general try to avoid mocking what you do not own. Instead encapsulate 3rd party dependencies behind an abstraction you control so as to allow you the flexibility to mock/stub/fake any desired behavior for testing.
Using MyClass1 from your example
public class MyClass1 : BaseClass2 {
public override int GenerateOutPut() {
var a = GetValue();
a += 1;
return a;
}
}
The following test can be done to verify the expected behavior from the subject under test. Note Moq allows for base members to be called by setting CallBase = true on the mocked object.
[TestClass]
public class MyClass1_Test {
[TestMethod]
public void MyClass1_Should_Generate_Output() {
//Arrange
var expected = 0;
var mock = new Mock<MyClass1>() {
CallBase = true //<-- let mock call base members
};
mock.Setup(_ => _.GetValue()).Returns(expected); // <-- mocked behavior
var sut = mock.Object; //<-- subject under test.
//Act
var actual = sut.GenerateOutPut();
//Assert
actual.Should().Be(expected + 1);
}
}
Which is almost like what you did manually but now via the mock proxy.

Related

Mocking a method on a property

I need to set the return value for a method returned by a property, basically I need to set what this does:
mockedObject.TheProperty.GetTheValues()
I just need it to return Enumerable.Empty<MyType>.
For the purposes of demonstrating that the functionality exists assuming
public interface IFoo {
IBar TheProperty { get; set; }
}
public interface IBar {
IEnumerable<MyType> GetTheValues();
}
public class MyType { }
Moq allows for auto mocking hierarchies otherwise known as recursive mocks
[TestClass]
public class RecursiveMocksTests {
[TestMethod]
public void Foo_Should_Recursive_Mock() {
//Arrange
IEnumerable<MyType> expected = Enumerable.Empty<MyType>();
var mock = new Mock<IFoo>();
// auto-mocking hierarchies (a.k.a. recursive mocks)
mock.Setup(_ => _.TheProperty.GetTheValues()).Returns(expected);
var mockedObject = mock.Object;
//Act
IEnumerable<MyType> actual = mockedObject.TheProperty.GetTheValues();
//Assert
actual.Should().BeEquivalentTo(expected);
}
}
Note that at no point was IBar ever initialized or configured. The framework will auto mock that interface because of the setup shown above.
If however, more functionality is needed from an IBar, then a proper mock should be done and configured accordingly. There is also nothing stopping the use of configuring multiple IBar members via the IFoo mock.
Reference Moq Quickstart: Properties
Imagine you have this:
public interface IA
{
IEnumerable<MyType> TheProperty { get; set; }
}
public class MyType {}
Then here is how to mock it so when TheProperty is called, it returns and IEnumerable.Empty<MyType>:
[TestMethod]
public void SomeTest()
{
/* Arrange */
var iAMock = new Mock<IA>();
iAMock.Setup(x => x.TheProperty).Returns(Enumerable.Empty<MyType>());
/* Act */
/* Assert */
}

Can I use moq Mock<MyClass> to mock a class, not an interface?

Going through https://github.com/Moq/moq4/wiki/Quickstart, I see it Mock an interface.
I have a class in my legacy code which does not have an interface. When I Mock<MyClass>, I get the following exception:
Additional information: Can not instantiate proxy of class: MyCompnay.Mylegacy.MyClass.
How can I use Moq to mock class from legacy code?
It is possible to Mock concrete classes
[TestClass]
public class PlaceholderParserFixture
{
public class Foo
{
public virtual int GetValue()
{
return 11;
}
}
public class Bar
{
private readonly Foo _foo;
public Bar(Foo foo)
{
_foo = foo;
}
public int GetValue()
{
return _foo.GetValue();
}
}
[TestMethod]
public void MyTestMethod()
{
var foo = new Mock<Foo>();
foo.Setup(mk => mk.GetValue()).Returns(16);
var bar = new Bar(foo.Object);
Assert.AreEqual(16, bar.GetValue());
}
}
but,
It must be a public class
The method to be mocked must be virtual
The messages I got for:
Making the class internal
Castle.DynamicProxy.Generators.GeneratorException: Type MoqFixture+Foo is not public. Can not create proxy for types that are not accessible.
or, having a non-virtual method
System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: mk => mk.GetValue()
do not match your cannot instantiate message, so something else seems to be wrong.
If you do not have a default constructor on the mocked object you can get that error message
e.g.
public class Foo
{
private int _value;
public Foo(int value)
{
_value = value;
}
public virtual int GetValue()
{
return _value;
}
}
one can get around this by passing values into the Mock<> ctor
e.g.
var foo = new Mock<Foo>(MockBehavior.Strict, new object[] { 11 });

Skip test method for specific type in generic test class

I'm trying to unit test a part of a project; I'm using NUnit. The targeted unit processes objects of several types, all extending a base type. I've created a generic test class on which I set the desired test types:
[TestFixture(typeof(SomeType))]
[TestFixture(typeof(SomeOtherType))]
class MyTestClass<T> where T : SomeBaseType, new()
{
[Test]
public void DoThisTest()
{
var sut = CreateSut();
var target = CreateTarget();
Assert.IsTrue(sut.Process(target));
}
[Test]
public void DoThatTest()
{
var sut = CreateSut();
var target = CreateInvalidTarget();
Assert.IsFalse(sut.IsValid(target));
}
//...
}
This creates a set of all the tests for each type set using TestFixture. For whatever reason, I have a test which only makes sense in the context of a specific type. This means that I need to either 1) use Assert.Ignore() on all other types or 2) create a different test class just for those "special" test cases.
Is there a way of opting out from a test from outside (attribute?) and specify that that particular test must not be "implemented" in certain contexts? I would like to "combine" 1) & 2) such that all the test cases are in the same file/class but some tests are only rendered/implemented/run for certain values set by TestFixture.
This isn't exactly what you're looking for, but I think it's a pretty close work around. You can specify nested classes within your main test fixture and decorate them with different TestFixture attributes to restrict what's run. It's probably best explained with an example. So, given these data types:
public interface ICompetitor {
string GetFinalPosition();
}
public class Winner : ICompetitor{
public string GetFinalPosition() {
return "Won";
}
}
public class Loser : ICompetitor {
public string GetFinalPosition() {
return "Lost";
}
}
I can define these TestFixtures:
[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> where T : ICompetitor, new()
{
static private T CreateSut() {
return new T();
}
[Test]
public void EverybodyHasPosition() {
Assert.IsNotNullOrEmpty(CreateSut().GetFinalPosition());
}
[TestFixture(typeof(Winner))]
public class WinnerTests {
[Test]
public void TestWon() {
Assert.AreEqual("Won", CompetitorTests<T>.CreateSut().GetFinalPosition());
}
}
[TestFixture(typeof(Loser))]
public class LoserTests {
[Test]
public void TestLost() {
Assert.AreEqual("Lost", CompetitorTests<T>.CreateSut().GetFinalPosition());
}
}
}
The EverybodyHasPosition test is run twice (once for the Winner and once for the Loser classes). Whereas the TestWon is only run for the Winner class and the TestLost is only run for the Loser class. It's not ideal, because you can only access static members of the outer class, and each fixture is responsible for it's own setup/teardown.
You can work around this though, by using a base class. So, the state sharing version might look more like this (notice that each TestFixture inherits from CompetitorTestsState):
public class CompetitorTestsState<T> where T : ICompetitor, new() {
protected T SUT { get; private set; }
[SetUp]
public void Setup() {
SUT = CreateSut();
}
private T CreateSut() {
return new T();
}
}
[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> : CompetitorTestsState<T> where T : ICompetitor, new() {
[Test]
public void EverybodyHasPosition() {
Assert.IsNotNullOrEmpty(SUT.GetFinalPosition());
}
[TestFixture(typeof(Winner))]
public class WinnerTests : CompetitorTestsState<T>{
[Test]
public void TestWon() {
Assert.AreEqual("Won", SUT.GetFinalPosition());
}
}
[TestFixture(typeof(Loser))]
public class LoserTests : CompetitorTestsState<T>{
[Test]
public void TestLost() {
Assert.AreEqual("Lost", SUT.GetFinalPosition());
}
}
}

Is it possible to "inherit" tests with xUnit.net?

I have a concrete class called EventManager and a subclass called ScheduledEventManager. I would like ScheduledEventManager to have to pass the same tests as EventManager plus a few additional ones. Is this possible with xUnit.net?
EDIT: I just realized that my case is a little more complicated than this. I'm using nested classes to keep my tests more organized. Example:
public class EventManagerTests
{
public class WhenAnEventIsFired
{
[Fact]
void ItNotifiesSubscribers()
{
// Perform the test
}
}
}
public class ScheduledEventManagerTests
{
// How to I inherit the above tests since they are in nested classes?
}
It seems to me that this is not possible, but maybe one of you geniuses knows something I don't.
Yes You can:
public abstract class EventManagerTests
{
protected IEventManager _ev;
protected EventManagerTests(IEventManager ev)
{
_ev = ev;
}
[Fact]
public void SharedTest()
{
// Perform _ev test
}
}
public class ScheduledEventManagerTests : EventManagerTests
{
public ScheduledEventManagerTests():base(new ScheduledEventManager())
{
}
// It will inherit tests from the base abstract class
}
public class UnScheduledEventManagerTests : EventManagerTests
{
public UnScheduledEventManagerTests():base(new UnScheduledEventManager())
{
}
// It will inherit tests from the base abstract class
}
Create a parameterized test that takes an instance of your base class as the SUT, and invoke the test with an instance of the sub class. Here's a (contrived) example using NUnit, which results in one passing and one failing test:
public class Foo
{
public virtual int DoSomething()
{
return 10;
}
}
public class Bar : Foo
{
public override int DoSomething()
{
return 9;
}
}
[TestFixture]
public class Tests
{
private Foo[] _foos = { new Foo(), new Bar() };
[Test]
[TestCaseSource("_foos")]
public void When_DoSomething_Is_Invoked_Then_A_Power_Of_Ten_Is_Returned(Foo sut)
{
Assert.That(sut.DoSomething() % 10, Is.EqualTo(0));
}
}

TDD How to Assert that a property of a POCO is set within a method that is being tested

We are creating a C# application using TDD and DI methodologies and NSubstitute.
We are writing a CreateThing method:
name and description strings as parameters
create a new Thing object
set the Name and Description properties of Thing from the method parameters
set the Status to Active
pass the Thing to a method on another class (via constructor injection) for further processing
We know how to write a test for the call to the other class by using Substitute.For and .Received().
How do we write tests for the Thing properties being set?
You can use Argument matchers namely Conditional matcher which looks like Arg.Is<T>(Predicate<T> condition). Your matcher could look like:
anotherClass.Received().Process(Arg.Is<Thing>(thing => !string.IsNullOrEmpty(thing.Name)));
Full listing:
public class Thing
{
public string Name { get; set; }
}
public class AnotherClass
{
public virtual void Process(Thing thing)
{
}
}
public class CreateThingFactory
{
private readonly AnotherClass _anotherClass;
public CreateThingFactory(AnotherClass anotherClass)
{
_anotherClass = anotherClass;
}
public void CreateThing()
{
var thing = new Thing();
thing.Name = "Name";
_anotherClass.Process(thing);
}
}
public class CreateThingFactoryTests
{
[Fact]
public void CreateThingTest()
{
// arrange
var anotherClass = Substitute.For<AnotherClass>();
var sut = new CreateThingFactory(anotherClass);
// act
sut.CreateThing();
// assert
anotherClass.Received().Process(Arg.Is<Thing>(thing => !string.IsNullOrEmpty(thing.Name)));
}
}

Categories

Resources