MOQ - Why is below not mocking? - c#

Anyone have any idea why below still calls YesService?
It almost seems like IYesService is considered separate to YesService..
Any ideas?
public interface IYesService
{
string Hello();
}
public class YesService : IYesService
{
public string Hello()
{
return "Yes";
}
}
class Program
{
static void Main(string[] args)
{
var _mock = new Mock<IYesService>();
_mock.Setup(x => x.Hello()).Returns("No");
var service = new YesService();
var result = service.Hello();
Console.Write(result);
Console.ReadLine();
}
}

Because you don't use the _mock, you instantiate the YesService and call the method on that.
You can use mocking when you consume this interface:
public class ServiceUser
{
private IYesService _yesService;
public ServiceUser(IYesService yesService)
{
_yesService = yesService;
}
public string CallService()
{
return _yesService.Hello();
}
}
Then use it like this:
var serviceMock = new Mock<IYesService>();
serviceMock.Setup(x => x.Hello()).Returns("No");
var service = new ServiceUser(serviceMock.Object);
var result = service.CallService();

You are creating an instance of YesService (the concrete class) in your Main method. The var service line an be done away with, and the var result line should become:
var result = _mock.Object.Hello();
Try that...

Related

How to create mock for method that is called using object instance in MOQ C#?

I created Test for a method that is being tested using MOQ & NUnit. The method to be tested will will another method using an object of that corresponding class. When I try to mock that called method, I am not able to invoke the mocked method. How to mock this method, because my testing method is using the other said method. Please help me on this.
public DataSet ExecuteCondition()
{
var ObjClass1 = new Class1();
....
var result = ObjClass1.VerifyPrecondition(query);
....
}
public class Class1:IClass1
{
public string VerifyPrecondition(string query)
{
....
return text;
}
}
So, I suppose this should look like this:
Class with ExecuteCondition() method:
public class DataClass
{
private readonly IClass1 _class1;
public DataClass(IClass1 class1)
{
_class1 = class1;
}
public DataSet ExecuteCondition()
{
//....
var result = _class1.VerifyPrecondition(query);
//....
}
}
Test:
[Test]
public void Test()
{
var mockClass1 = new Mock<IClass1>();
mockClass1.Setup(x => x.VerifyPrecondition(It.IsAny<string>())).Returns("test");
var dataClass = new DataClass(mockClass1.Object);
dataClass.ExecuteCondition();
//Assert
}

Mock a method in another static class c#

I want to ask the best way how to mock static a method in an another class. I know that mock is not working for a static class. Here is my Code so far. I don't want to call SearchSomething() at the time because it's external interaction
public ResponseBase GetData(string searchId)
{
try
{
var request = new SearchRequest
{
SearchId = searchId
};
var response = SearchLogic.SearchSomething(request);
return response;
}
catch (Exception e)
{
return ResponseBase.ExceptionHandling(e);
}
}
public class SearchLogic(){
public static ResponseBase SearchSomething(SearchRequest request)
{
//Do Something
return new ResponseBase;
}
}
This is my UnitClass
[TestClass]
public class UnitClass
{
[TestMethod]
public void PositiveSearchTest()
{
//arrange
string searchId = "name";
var expected = new SearchRequest();
SearchtController search = new SearchtController();
var staticMock = new Mock<SearchLogic>();
staticMock.Setup(s => s.SearchSomething()).Returns(new ResponseBase());
//act
var actual = search.GetData(searchId);
//assert
Assert.AreEqual(actual, expected);
}
}
While this question gives one way to solve this, my preferred solution would be different: modify SearchLogic so it is no longer static. After that, you can then mock it to your heart's content. Static methods are always a complete pain for unit testing; I try to use them only for situations where there is one and only one correct behaviour.
This obviously assumes you have the ability to modify SearchLogic. If you don't, see the linked question.

Moq SetupSequence doesn't work

I try to use the SetupSequence method of the Moq 4.5 framework.
Class that should be mocked:
public class OutputManager {
public virtual string WriteMessage(string message) {
// write a message
}
}
Mock:
var outputManagerMock = new Mock<OutputManager>();
var writeMessageCalls = 0;
var currentMessage = String.Empty;
outputManagerMock.Setup(o => o.WriteMessage(It.IsAny<string>())).Callback((string m) => {
writeMessageCalls++;
message = m;
});
This code works fine. But I'd like having a different setup for each call of the WriteMessage method. Well, I use SetupSequence instead of Setup:
var outputManagerMock = new Mock<OutputManager>();
var writeMessageCalls = 0;
var firstMessage = String.Empty;
var secondMessage = String.Empty;
outputManagerMock.SetupSequence(o => o.WriteMessage(It.IsAny<string>()))
.Callback((string m) => {
writeMessageCalls++;
firstMessage = m;
}).Callback((string m) => {
writeMessageCalls++;
secondMessage = m;
});
Then I've got the error:
Error CS0411 The type arguments for method
'SequenceExtensions.SetupSequence<TMock, TResult>(Mock<TMock>,
Expression<Func<TMock, TResult>>)' cannot be inferred from the usage.
Try specifying the type arguments explicitly.
I've found the possible solution here - SetupSequence in Moq. But it looks like a workaround.
SetupSequence is used to setup a sequence of returns based on the number of the attempt to use the method that is being set up. An example based on your code which demonstrates what I am talking about :
outputManagerMock.SetupSequence(o => o.WriteMessage(It.IsAny<string>()))
.Returns("Hello for the first attempt!")
.Returns("This is the second attempt to access me!")
.Throws(new Exception());
If OutputManager is a dependency for other classes then you should consider abstracting that class to make it easier to mock for your tests.
public interface IOutputManager {
string WriteMessage(string message);
}
That would then mean that the implementation of this interface would look like what you had originally with the addition of the interface.
public class OutputManager : IOutputManager {
public string WriteMessage(string message) {
// write a message
}
}
Given that you originally attempted to mock OutputManager then the assumption here is that it is not the system under test as you typically do not mock the target of the test but rather its dependencies.
So let's assume a dependent class looked something like this.
public class DependentOnIOutputManager {
private IOutputManager outputManager;
public DependentOnIOutputManager(IOutputManager outputManager) {
this.outputManager = outputManager;
}
public string SomeMethod(string message) {
// write a message
var output = outputManager.WriteMessage(message);
//...other code
return output;
}
}
Then an example test could look like this.
[TestMethod]
public void Moq_SetupSequence_Example() {
//Arrange
var mock = new Mock<IOutputManager>();
mock.SetupSequence(x => x.WriteMessage(It.IsAny<string>()))
.Returns("first")
.Returns("second")
.Throws<InvalidOperationException>();
var outputManager = mock.Object;
var sut = new DependentOnIOutputManager(outputManager);
//Act
var first = sut.SomeMethod("1st");
var second = sut.SomeMethod("2nd");
Exception e = null;
try {
sut.SomeMethod("3rd");
} catch (InvalidOperationException ex) {
e = ex;
}
//Assert
Assert.IsNotNull(first);
Assert.IsNotNull(second);
Assert.IsNotNull(e);
}

Mocking delegates with Moq

I have an interface:
public interface IRepeater
{
void Each(string path, Action<string> action);
}
I want to mock this interface using Moq. Now I can obviously do the following:
var mock = new Mock<IRepeater>();
mock.Setup(m => m.Each(It.IsAny<string>(), It.IsAny<Action<string>>());
However, to aid testing I want to be able to mock the string that gets passed to the Action<string>. Can this be done with Moq? If yes, how?
Update
To clarify I am testing a different class that has a dependency on IRepeater. I want to mock IRepeater.Each so I can control the string that the Action gets so I can test the behaviour.
Example
So if I have a class like so.
public class Service
{
private readonly IRepeater _repeater;
public Service(IRepeater repeater)
{
_repeater = repeater;
}
public string Parse(string path)
{
var builder = new StringBuilder();
_repeater.Each(path, line => builder.Append(line));
return builder.ToString();
}
}
How do I mock IRepeater.Each so that I can test Service.Parse?
You have to use callback method. Since line => builder.Append(line) is part of the method behavior, you have to execute this behavior when you test the method:
[TestMethod]
public void Test_Service_When_Passing_String_And_ActionDelegate()
{
var fakeReporter = new Mock<IRepeater>();
fakeReporter.Setup(x => x.Each(It.IsAny<string>(), It.IsAny<Action<string>>()))
.Callback<string, Action<string>>((s, action) => action(s));
var target = new Service(fakeReporter.Object);
var result = target.Parse("asdfghj");
Assert.AreEqual("asdfghj", result);
}
Another approach to test this method is to verify the method was called with the correct path and then verify that the action is the correct action:
[TestMethod]
public void Test_Service_When_Passing_String_And_ActionDelegate()
{
var fakeReporter = new Mock<IRepeater>();
fakeReporter.Setup(x => x.Each(It.IsAny<string>(), It.IsAny<Action<string>>()))
.Callback<string, Action<string>>((s, action) =>
{
Assert.AreEqual("asdfghj", s);
foreach (var w in "pass")
{
action(w.ToString());
}
});
var target = new Service(fakeReporter.Object);
var result = target.Parse("asdfghj");
Assert.AreEqual("pass", result);
}
BTW you can replace the It.IsAny<string>() with the string and then remove the Assert.AreEqual("asdfghj", s);(I just like to test things in the explicit way...)
Seems like you are looking to verify that a passed Action (delegate) will be passed to the IRepeater Call. Because you are not testing the Repeater but a Repeater caller (The Repeater is the mock and not the tested subject).
Here is how I would have done it:
public class Service
{
private readonly IRepeater repeater;
public Service(IRepeater repeater)
{
this.repeater = repeater;
}
public void Foo(string str, Action<string> action)
{
repeater.Each(str, action);
}
}
public class ActionImplement
{
public virtual void Action(string str)
{
Console.Write(str);
}
}
public interface IRepeater
{
void Each(string path, Action<string> action);
}
And the test would have verify the passing of ActionImplement.Action
[TestMethod]
public void Test_Service_When_Passing_String_And_ActionDelegate()
{
var actionImplement = new Mock<ActionImplement>();
actionImplement.Setup(m => m.Action(It.IsAny<string>()));
var mock = new Mock<IRepeater>();
mock.Setup(m => m.Each(It.IsAny<string>(), actionImplement.Object.Action));
var srv = new Service(mock.Object);
srv.Foo("aa",actionImplement.Object.Action);
mock.Verify(ai => ai.Each("aa", actionImplement.Object.Action));
}

Derived public method in class

I'm trying to test with Microsoft Fakes code in a application which sort of the following construction in a library:
public static class C
{
public A GetConfigurationFactory(Uri uri);
}
public class A : B
{
public A(Uri uri)
{
}
}
public class B
{
public void Authenticate()
{
}
}
I've created the following test for this in Visual Studio:
//Arrange
ShimA.ConstructorUri = (#this, value) =>
{
var shim = new ShimA(#this);
};
ShimC.GetConfigurationFactory = (uri) =>
{
var shim = new A(uri);
return shim;
};
var uri1 = new Uri("http://test-url");
//Act
A.Authenticate()
I get a null pointer when I call the Authenticate method from instance A.
Does anyone how I can solve this? I already looked and there is no overloaded constructor.
Solved this problem with the following code:
ShimB.AllInstances.Authenticate = (someValue) => { return; }
This code ensures that when I call the Authenticate method from any class it will always return the specified value.

Categories