Create new instance from Moq.object failed unit test - c#

I am trying to instantiate a new object using the moq that I have set up but I am not getting the data I've set up in moq. Why?
For instance: I've set up MyMethod() to true in mock. But when I create the new instance from mock.object I am getting false for MyMethod().
Interface:
public interface IMyClass
{
bool MyMethod();
}
Class
public class MyClass : IMyClass
{
public MyClass(IMyClass myClass)
{
}
public bool MyMethod()
{
return false;
}
public string DoSomething()
{
if(MyMethod() == false)
{
// do something
return "did something";
}
else
{
// do something else
return "did something else";
}
}
}
TestMethod
[TestMethod]
public void MyMethodTest()
{
var moq = new Mock<IMyClass>();
moq.Setup(m => m.MyMethod()).Returns(true);
var sut = new MyClass(moq.Object);
Assert.AreEqual(sut.DoSomething(), "did something else"); // Actual: "did something" Expected: "did something else"
}

The test fails because you are not assigning any value in the class to the public member being compared.
MyClass.MyProperty is never assigned a value, so in
Assert.AreEqual(sut.MyMethod(), true);
sut.MyMethod() will be false
You would need to refactor the class to use the value from the injected interface and assign it to the respective member.
public class MyClass : IMyClass {
public bool MyProperty { get; set; }
public bool MyMethod() {
return MyProperty;
}
public MyClass(IMyClass myClass) {
this.MyProperty = myClass.MyProperty; // assigning value to property
}
}

Related

Make class return a field

Is there a way to make a class return one of its fields by default like that:
public class TestClass
{
public string something;
}
TestClass test = new TestClass();
test = "alpha"; // "alpha" string is assigned to "something"
Console.Write(test); // test returns "alpha" string from "something"
How to make this work?
For all those saying that's impossible,)
public class TestClass
{
public string something;
public static implicit operator TestClass(string s) => new TestClass { something = s};
public static implicit operator string(TestClass testClass) => testClass.something;
}
Usage:
TestClass test = new TestClass();
test = "alpha";
Console.WriteLine(test);
Gives:
alpha
Note: Console.WriteLine takes test as string and calls Console.WriteLine(string value) overload thanks to implicit conversion.
You can't make "a class return a field", but you can override its ToString method, so when it's printed with something like Console.Write you'll get the output you want:
public class TestClass
{
public string Something {get; set;}
public override string ToString()
{
return Somethig;
}
}
I would prefer to use the constructor and overload method ToString(), so you get an immutable object.
public class TestClass
{
private readonly string something;
public TestClass(string something)
{
this.something = something;
}
public override string ToString()
{
return something;
}
}
TestClass test = new TestClass("alpha");
Console.Write(test);
Is there a way to make a class return one of its fields by default?
No. Classes are not designed to return any value.
An alternative way to achieve what you mentioned in your question is defining property with get; set;, something like:
public class TestClass
{
public string Something { get; set; }
}
which you can use like:
TestClass test = new TestClass();
test.Something = "alpha"; // "alpha" string is assigned to "something"
Console.Write(test.Something); // test returns "alpha" string from "something"

How to spy method return value by NSubstitute

I want to spy return value of a mocked method of a mocked interface in NSubstitute. I get return value of Received function but it always returns null.
public interface IFactory
{
object Create();
}
public interface IMockable
{
object SomeMethod();
}
public class Mockable : IMockable
{
private readonly IFactory factory;
public Mockable(IFactory factory)
{
this.factory = factory;
}
public object SomeMethod()
{
object newObject = factory.Create();
return newObject;
}
}
public class TestClass
{
[Fact]
void TestMethod()
{
var factory = Substitute.For<IFactory>();
factory.Create().Returns(x => new object());
IMockable mockable = new Mockable(factory);
object mockableResult = mockable.SomeMethod();
object factoryResult = factory.Received(1).Create();
Assert.Equal(mockableResult, factoryResult);
}
}
I expect that mockableResult and factoryResult be equal but factoryResult is null.
That is because you are using it incorrectly. Received is an assertion on the called method. It does not return a usable value from mocked members.
Review the follow modified version of your test that behaves as you would have expected.
public class TestClass {
[Fact]
void TestMethod() {
//Arrange
object factoryResult = new object(); //The expected result
var factory = Substitute.For<IFactory>();
factory.Create().Returns(x => factoryResult); //mocked factory should return this
IMockable mockable = new Mockable(factory);
//Act
object mockableResult = mockable.SomeMethod(); //Invoke subject under test
//Assert
factory.Received(1).Create(); //assert expected behavior
Assert.Equal(mockableResult, factoryResult); //objects should match
}
}

How to pass mocked interface object to the main class c#

I have the below code :
public interface Iinterface
{
Task<bool> RetrieveFromDataBase();
}
public class Class1 : Iinterface
{
public async Task<bool> RetrieveFromDataBase()
{
//do something
return true;
}
}
public class AnotherClass
{
Class1 c = new Class1();
public AnotherClass(Class1 obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
Now, I'm trying to write test cases for ExecuteData method. In this method I need to bypass RetrieveFromDataBase method. So I'm trying to mock it. This is the below code I have written.
[TestClass()]
public class AnotherClassTests
{
[TestMethod()]
public async Task ExecuteDataTest()
{
Task<bool> retValue = RetrieveFromDataBaseMoq(); // this returns true
var moq = new Mock<Iinterface>();
moq.Setup(x => x.RetrieveFromDataBase()).Returns(retValue);
AnotherClass obj = new AnotherClass((Class1)moq.Object); // error thrown from here
var result = await obj.ExecuteData();
Assert.IsTrue(result);
}
}
The mocking which is done is successful, i.e it doesn't throw any error. The problem I'm facing here is when I pass this mocked object a parameter to the constructor, it is throwing error System.InvalidCastException : Unable to cast object "Castle.Proxies.Iinterface" to type "Class1".
I know that it is not able to convert mocked interface to the concrete class type. But is there a way to rectify this error or pass the mocked object to the main class in anyway.
Many thanks!
you should declare variable c as an Iinterface. That's one of the advantages of using interfaces. You should dependend on the contract(interface) , instead of concrete implementations. Following that you are not coupled to concrete classes.
public class AnotherClass
{
Iinterface c; //I removed the default new since it will get assigned in constructor
public AnotherClass(Iinterface obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
The problem here I'm facing is, the class Class1 has some other methods and variables as well which are not declared in the interface.
You could do a composition inside Class1, and move the TInterface as a dependency inside Class1. Keep in mind that the interface is what you will get mocked in unit test
public class Class1
{
public TIinterface tinterface{get;private set;}
public Class1(TIinterface interface)
{
tinterface= interface;
}
}
public class YourCustomImplementation:TIinterface
{
public async Task<bool> RetrieveFromDataBase()
{
//do something
return true;
}
}
public class AnotherClass
{
Class1 c = new Class1();
public AnotherClass(Class1 obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.tinterface.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}

Moq an object created inside the method being tested

In the following example, I want to test the TestMe.DoSomething() function.
I want to mock the ISomething interface that is used within this method and make it return different values (depending on the specific unit test.)
In real life the ISomething interface winds up calling out to expensive 3rd party resources -- I definitely don't want to just call a real ISomething.
Here is the example structure:
class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
interface ISomething
{
int Run();
}
class Something : ISomething
{
public int Run()
{
return 1;
}
}
Here is code that doesn't work:
var fakeSomething = new Mock<ISomething>();
var testMe = new TestMe();
Mock.Get(testMe).Setup(p => p.SomethingFactory()).Returns(fakeSomething.Object);
testMe.DoSomething();
Because SomethingFactory() is private, I cannot set the return value from that method to be what I want.
Any advice on how I can solve this?
Make the factory a full interface / class and remove the SomethingFactory method from TestMe.
public interface ISomethingFactory {
ISomething MakeSomething();
}
public sealed class SomethingFactory {
public ISomething MakeSomething() {
return new Something();
}
}
class TestMe
{
private readonly ISomethingFactory _somethingFactory;
public TestMe(ISomethingFactory somethingFactory) {
_somethingFactory = somethingFactory;
}
public void DoSomething()
{
ISomething s = _somethingFactory.MakeSomething();
int i = s.Run();
//do things with i that I want to test
}
}
This will allow you to mock ISomethingFactory to return a mock of ISomething.
While I think you may protest this solution as too drastic a change, I think its better than making a class that's not sealed with a members who's only reason for being virtual is for testing.
You can inject your dependency. If you don't want to break all your callers you can add two constructors and use the one that lets you inject fake in tests
class TestMe
{
private readonly ISomething something;
TestMe() : this(new RealSomething()
{
}
TestMe(ISomething sth)
{
something = sth;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
Second way would be to change the
SomethingFactory
method to protected virtual and override it in derived class and use that class instead, or to setup
class TestableTestMe : TestMe
{
private readonly ISomething something;
TestableTestMe(ISomething testSpecific)
{
something = testSpecific;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected override ISomething SomethingFactory()
{
return something;
}
}
This technique is called "extract and override"
Changing SomethingFactory() to be protected virtual allows you to use Moq.Protected to access the method by its name:
public class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected virtual ISomething SomethingFactory()
{
return new Something();
}
}
public interface ISomething
{
int Run();
}
public class Something : ISomething
{
public int Run()
{
return 1;
}
}
So you can run this test:
var fakeSomething = new Mock<ISomething>();
fakeSomething.Setup(p => p.Run()).Returns(2);
var testMe = new Mock<TestMe>();
testMe.Protected().Setup<ISomething>("SomethingFactory").Returns(fakeSomething.Object);
testMe.Object.DoSomething();

Overloading with argument types that are base and inherited class

I have something like this:
class BaseArg { }
class DerivedArg : BaseArg { }
interface IDoSomething
{
void DoSomething();
}
class A : IDoSomething
{
public BaseArg Value { get; set; }
public A(BaseArg value)
{
this.Value = value;
}
public static A Create(BaseArg arg)
{
return new A(arg);
}
public static B Create(DerivedArg arg)
{
return new B(arg);
}
public virtual void DoSomething()
{
}
}
class B : A
{
public DerivedArg DerivedValue { get; set; }
public B(DerivedArg value)
: base(value)
{
this.DerivedValue = value;
}
public override void DoSomething()
{
// does something different from A.DoSomething()
// uses additional stuff in DerivedArg
}
}
However, even when I do this:
DerivedArg arg = new DerivedArg();
A a = A.Create(arg);
A.Create(BaseArg arg) is called (and thus A is created, which was not the intention).
Am I missing something here? If so, how should I rewrite this without using weird stuff such as conditions on arg as DerivedArg.
The correct factory method is getting executed. Set a breakpoint inside of:
public static B Create(DerivedArg arg)
{
return new B(arg); /* set breakpoint */
}
It appears to you that it isn't being executed since you've defined the local variable of type A:
A a = A.Create(arg);
public static B Create(DerivedArg arg) is being called properly and an instance of type B is being returned and boxed as type A.

Categories