Verify a private method gets call Unit Test - c#

I have an interface with a method like this:
public string GetImageSrc(string input);
The implementation of this is below:
public string GetImageSrc(string input)
{
if (input.ContainsImage())
{
DoWork();
}
return input;
}
My string extension for ConatinsImage is:
public static bool ContainsImage(this string input)
{
if (!string.IsNullOrEmpty(input))
{
return input.Contains("img");
}
return false;
}
DoWork is a private method in the class. I am writing Unit Tests for the class - I am passing null to the method and doing an assert that null is returned. However is there a way I can Assert the invocation of the DoWork private method is None for a null input?

I recommend creating a new interface IWorker with a DoWork() method, then inject it into the constructor of the class that contains the GetImageSrc() method. In your unit test, you could then inject a mock object of the interface, and verify DoWork() was called or not:
public interface IWorker
{
void DoWork();
}
public class YourClass
{
private readonly IWorker _worker;
public YourClass(IWorker worker)
{
_worker = worker;
}
public string GetImageSrc(string input)
{
if (input.ContainsImage())
{
_worker.DoWork();
}
return input;
}
}
Test using Microsoft.VisualStudio.TestTools.UnitTesting and Moq:
[TestMethod]
public void GetImageSrc_GivenNull_ReturnsNull_And_WorkerNotCalled()
{
var mockWorker = new Mock<IWorker>();
var testSubject = new YourClass(mockWorker.Object);
var response = testSubject.GetImageSrc(null);
Assert.IsNull(response);
mockWorker.Verify(x => x.DoWork(), Times.Never());
}

Related

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;
}
}

How to use an interface within a public interface with a main?

//Program.cs
public interface TestVal
{
//Input Param
string Input { get; }
//will return output
TestValRes ValidateRe(string input);
}
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}
//TestvalRes.cs
public interface TestvalRes
{
string Input { get; }
bool IsValid { get; }
}
So I just want to pass a string to the TestVal, do validation and call TestvalRes to return whether it is Valid or not, and if Invalid, why? So the validation will be done in the first public interface - TestVal, however I still need to call it inside the Main(), right?
First off, I'd recommend following C# naming conventions and name your interfaces ITestVal and ITestValRes respectively.
Next, static method cannot call instance methods in the same class (without creating an instance and using that). You need to create an instance of the class and pass control of the application flow to that:
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}

Compare Action<T>

I have a service class as below:
public class MyService
{
private readonly IMyDependency _myDependency;
public MyService(IMyDependency myDependency)
{
_myDependency = myDependency;
}
public void MyHandler(string param)
{
// work
}
public void AnotherMethod()
{
_myDependency.DoWork(MyHandler);
}
}
How can I Unit Test that MyHandler has been given as a parameter of DoWork()?
Since you are using Moq, you can write test like this:
[TestMethod]
public void DoWorkWasCalledWithCorrectParameters()
{
var mock = new Moq.Mock<IMyDependency>();
var myService = new MyService(mock.Object);
myService.AnotherMethod();
// verify that method was called once and with correct parameter:
mock.Verify(x => x.DoWork(myService.MyHandler), Moq.Times.Once);
}

Assertion of void asynchronous method

I have a class similiar to this:
public class MyClass
{
public Task MyMethod()
{
//do something
}
}
As described, 'MyMethod' is asynchronous, lets say for simplicity that this is it's implementation:
public Task MyMethod()
{
return Task.Run(() =>
{
var success = _someService.DoSomething();
if (!success) throw new Exception("unsuccsesfull");
});
}
Obviously, when MyMethod awaitable callback will run it means that no exception was thrown in the running thread, meaning 'MyMethod' invocation was successfull.
I want to test this method. The test method to will look like:
[Test]
public async void TestMyMethod_TestInitialState_TestExpectedResult()
{
// test initialization..
//...
//..
var myClass = new MyClass();
await myClass.MyMethod();
Assert.That(????)
}
My question - what is the correct assertion?
I have a possible solution - add a logical member to 'MyClass' and update this member according to the method result:
public class MyClass
{
public bool SomeMember { get; private set; }
public Task MyMethod()
{
Task.Run(() =>
{
SomeMember = _someService.DoSomething();
if (!SomeMember ) throw new Exception("unsuccsesfull");
});
}
}
That way I can assert the test like this:
[Test]
public async void TestMyMethod_TestInitialState_SomeMemberShouldBeTrue()
{
// test initialization..
//...
//..
var myClass = new MyClass();
await myClass.MyMethod();
Assert.True(SomeMember)
}
}
However, I dont like this solution because I'm adding a property to 'MyClass' just to be able to assert a test, I dont really need this property in my bussiness world. Also each property added to a class represents some state of this class and adds a level of comlexity.
Suggestions?
Guy.
You want what's called a "mock" or "stub". The idea is that you refactor your code so that it has a dependency on an interface, then you mock the interface while testing.
There are various frameworks/tools that help out with mocking (Moq, Microsoft Fakes, TypeMock Isolator, JustMock, etc), and there are also many frameworks that help out with the closely related problem of dependency injection (Unity, Castle Windsor, StructureMap, Autofac, etc).
But you can start off just doing it yourself. First, refactor MyClass so it depends on ISomeService:
public interface ISomeService
{
bool DoSomething();
}
public class MyClass
{
private readonly ISomeService _someService;
public MyClass(ISomeService someService)
{
_someService = someService;
}
public Task MyMethod()
{
return Task.Run(() =>
{
var success = _someService.DoSomething();
if (!success) throw new Exception("unsuccsesfull");
});
}
}
Then in your unit test:
private class TestService : ISomeService
{
public bool DoSomethingReturnValue { get; set; }
public bool DoSomething() { return DoSomethingReturnValue; }
}
[Test]
public async Task TestMyMethod_TestInitialState_TestExpectedResult()
{
var myClass = new MyClass(new TestService { DoSomethingReturnValue = true });
await myClass.MyMethod();
}
[Test]
public async Task TestMyMethod_TestInitialState_TestFailure()
{
var myClass = new MyClass(new TestService { DoSomethingReturnValue = false });
Assert.Throws(() => myClass.MyMethod()); // (I'm unsure of the exact NUnit syntax)
}

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();

Categories