UnexpectedArgumentMatcherException when calling Setup second time - c#

I have these two tests (stripped to the bare bones to replicate the error):
[TestFixture]
public class CreditorMapperTests
{
private IAbcContext _AbcContext;
[SetUp]
public void Setup()
{
_AbcContext = Substitute.For<IAbcContext>();
_AbcContext.CompanyInfo.Returns(x => new CompanyInfo(Arg.Any<Guid>()));
}
[Test]
public void A()
{
Creditor publishDocument = new Creditor();
publishDocument.CompanyExternalId = _AbcContext.CompanyInfo.UniqueId;
}
[Test]
public void B()
{
Creditor publishDocument = new Creditor();
publishDocument.CompanyExternalId = _AbcContext.CompanyInfo.UniqueId;
}
}
public interface IAbcContext
{
CompanyInfo CompanyInfo { get; }
}
public class CompanyInfo
{
public CompanyInfo(Guid uniqueId)
{
UniqueId = uniqueId;
}
public readonly Guid UniqueId;
}
public class Creditor
{
public Guid CompanyExternalId { get; set; }
}
The Setup() for A() runs fine. However when Setup() is called for B(), I get this error:
NSubstitute.Exceptions.UnexpectedArgumentMatcherException : Argument
matchers (Arg.Is, Arg.Any) should only be used in place of member
arguments. Do not use in a Returns() statement or anywhere else
outside of a member call. Correct use:
sub.MyMethod(Arg.Any()).Returns("hi") Incorrect use:
sub.MyMethod("hi").Returns(Arg.Any())
This only happens when I run both tests by running all tests in that class.
If I run B() by itself, the Exception is not thrown.
Why does Setup() for B() fail only when run automatically after A()?
(nb. both tests are identical).
I'm using NUnit v3.8.1 and NSubstitute v2.0.3

Related

How to use mock which is not passed to real object

I have service CarTankService as shown below. It has Add method which i want to test. To be more detailed i would like to check whether AddTank (inside Add) will be reached.
public class CarTankService : ICarTankService
{
private readonly ITankQuery _tankQuery;
private readonly CarClient _carClient;
public CarTankService(ITankQuery tankQuery)
{
_tankQuery = tankQuery;
_carClient = new CarClient();
}
public ObservableCollection<CarTank> GetTanks() => _carClient.Tanks;
public void GenerateNewList() => _carClient.GenerateNewTanksList();
public virtual void Add(CarTank tank)
{
if (_tankQuery.isExist(tank.Number)) throw new OwnException()
_carClient.AddTank(tank);
}
public virtual void Remove(CarTank tank) => _carClient.RemoveCarTank(tank);
}
This is my test method class:
[TestFixture]
class CarTankServiceTests
{
private Mock<ITankQuery> TankQuery { get; set; }
private ICarTankService CarTankService { get; set; }
private Mock<CarClient> CarClient { get; set; }
[SetUp]
public void SetUp()
{
TankQuery = new Mock<ITankQuery>();
CarClient = new Mock<CarClient>();
CarTankService = new CarTankService(TankQuery.Object);
}
[Test]
public void Add_NotExistReferenceNumber_AddTankReached()
{
TankQuery.Setup(uow => uow.isExist(It.IsAny<int>())).Returns(false);
CarTankService.Add(new CarTank());
CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);
}
}
CarClient.Verify for AddTank always show it was 0 occurence in test, which in this case is not true. I am not sure but I think it's because CarClient model class because it's not injected directly insdie my service it always shows 0. AM i right? Is there any option to test it?
If you mock your CarClient you have to setup all methods you want to use in your test (here AddTank). In you code we have two CarClient instances, one is mocked in your test and another is initialized in your constructor of CarTankService. So, you are calling the latter case while verifying the mocked one.
If you convert the CarClient to an interface and inject it, The solution is something like this:
[TestFixture]
class CarTankServiceTests
{
private Mock<ITankQuery> TankQuery { get; set; }
private ICarTankService CarTankService { get; set; }
private Mock<CarClient> CarClient { get; set; }
[SetUp]
public void SetUp()
{
TankQuery = new Mock<ITankQuery>();
CarClient = new Mock<CarClient>();
CarTankService = new CarTankService(TankQuery.Object);
}
[Test]
public void Add_NotExistReferenceNumber_AddTankReached()
{
TankQuery.Setup(uow => uow.isExist(It.IsAny<int>())).Returns(false);
CarTankService.Add(new CarTank());
CarClient.Setup(a=>a.AddTank(/*write you loginc*/));
CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);
}
}
Here is more explanation:
When you write CarTankService = new CarTankService(TankQuery.Object); in your test, it creates a new instance on your class (_carClient = new CarClient();), so the class has it's own instance, while the test class has it own too (CarClient = new Mock<CarClient>();) which is mocked. This line of code CarTankService.Add(new CarTank()); adds the tank to the instance of class, while in your test, you are verifying the instance of test class which has no tank (CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);).

Partial mock methods in a class using Autofixture, Moq and XUnit

I want to mock only some methods of a class and call the real implementation for other methods.
I have my sut class Test where the Runner class is injected in the constructor. This injected class has again a injected other class RunnerParam in the constructor.
The code is a simplified case of my real classes in trying to have only the basics.
[Fact]
public void Test()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var paramMock = fixture.Freeze<Mock<IRunnerParam>>();
paramMock.Setup(x => x.Multiplicator()).Returns(2);
var classMock = fixture.Freeze<Mock<IRunner>>();
classMock.Setup(x => x.Run()).Returns(5);
var test = fixture.Create<Test>();
var result = test.StartRunning(); // should be 5
var result2 = test.StartRunningImplementation(5); // should be 500
}
Supporting members
public interface IRunnerParam
{
int Multiplicator();
}
public class RunnerParam : IRunnerParam
{
public virtual int Multiplicator()
{
return 20;
}
}
public interface IRunner
{
int Run();
int RunImplementation(int param);
}
public class Runner : IRunner
{
protected virtual RunnerParam MultiParam { get; set; }
public Runner(RunnerParam multiParam)
{
MultiParam = multiParam;
}
public virtual int Run()
{
return 10;
}
public int RunImplementation(int param)
{
return 10 * MultiParam.Multiplicator() * param * Run();
}
}
public class Test
{
private readonly IRunner _runner;
public Test(IRunner runner)
{
_runner = runner;
}
public int StartRunning()
{
return _runner.Run();
}
public int StartRunningImplementation(int param)
{
return _runner.RunImplementation(param);
}
}
I want to mock and give a mocked value to the method Run in the class Runner, but to use the real implementation of the method RunImplementation.
I would expect to see for result2 500, but it's 0, meaning that the method is not seen as mocked up. In my eyes that is correct, but the Moq callbase is equal to true, so the real implementation should be taken, but it isn't.
What am I missing here?
In the shown simplified example, Test is only dependent on IRunner
private readonly IRunner _runner;
public Test(IRunner runner)
{
_runner = runner;
}
So that is all that needs to be mocked if the intention was to test Test class in isolation.
//...
var classMock = fixture.Freeze<Mock<IRunner>>();
classMock.Setup(x => x.Run()).Returns(5);
classMock.Setup(x => x.RunImplementation(It.IsAny<int>())).Returns(500);
//...
If Runner class is to be also tested in isolation, then a mocked RunnerParam would be needed to satisfy its dependencies.
It should however be dependent on the abstraction (interface) and not the concretion (implementation).
protected virtual IRunnerParam MultiParam { get; set; }
public Runner(IRunnerParam multiParam) {
MultiParam = multiParam;
}
This simplifies the isolated test as described in the original question
I want to mock and give a mocked value to the method Run in the class Runner, but to use the real implementation of the method RunImplementation.
//Arrange
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var runnerParam = fixture.Freeze<Mock<IRunnerParam>>()
.Setup(_ => _.Multiplicator())
.Returns(2);
var subjectMock = fixture.Freeze<Mock<Runner>>();
subjectMock.CallBase = true;
subjectMock.Setup(_ => _.Run()).Returns(5);
int expected = 500;
Runner sut = subjectMock.Object;
//Act
var actual = sut.RunImplementation(5); // should be 500
//Assert
actual.Should().Be(expected);

Assert and Verify both fail

Please see the code below:
[TestClass]
public class UnitTest1
{
Moq.Mock<ISayGoodMorning> GoodMorningMock;
[TestInitialize]
public void init()
{
GoodMorningMock = new Moq.Mock<ISayGoodMorning>();
GoodMorningMock.Setup(x => x.GoodMorning()).Returns(Test());
}
[TestMethod]
public void TestMethod1()
{
GoodMorningMock.Verify(x => x.GoodMorning(), Times.Once());
Assert.AreEqual(g.SayGreeting(), "Hola");
}
public string Test()
{
return "Hola";
}
}
The assert and the verify fail. Why is that? Here is the code that is tested:
namespace ClassLibrary1
{
public class SayGoodMorning : ISayGoodMorning
{
public string GoodMorning()
{
return "Good Morning";
}
}
public interface ISayGoodMorning
{
string GoodMorning();
}
}
namespace ClassLibrary2
{
public class Greeting
{
public string SayGreeting()
{
ISayGoodMorning s = new SayGoodMorning();
return s.GoodMorning();
}
}
}
First the subject under test needs to be refactored to inject the dependency to allow a mock to be used when testing. Either via constructor or method injection. (Explicit Dependencies Principle)
This example uses constructor injection
namespace ClassLibrary2 {
public class Greeting {
private readonly ISayGoodMorning speaker;
public Greeting(ISayGoodMorning speaker) {
this.speaker = speaker;
}
public string SayGreeting() {
return speaker.GoodMorning();
}
}
}
Next the test needs to be restructured so that the Verify is done after exercising the method under test;
[TestClass]
public class UnitTest1 {
Mock<ISayGoodMorning> GoodMorningMock;
[TestInitialize]
public void init() {
//Arrange
GoodMorningMock = new Mock<ISayGoodMorning>();
GoodMorningMock.Setup(_ => _.GoodMorning()).Returns(Test());
}
[TestMethod]
public void TestMethod1() {
//Arrange cont'd
var g = new ClassLibrary2.Greeting(GoodMorningMock.Object);
var expected = "Hola";
//Act
var actual = g.SayGreeting();
//Assert
GoodMorningMock.Verify(_ => _.GoodMorning(), Times.Once());
Assert.AreEqual(expected, actual);
}
public string Test() {
return "Hola";
}
}

Issue with Unit Testing Model View Presenter

I am creating an application in ASP.NET web form with MVP pattern. I am getting some issues working with TDD. I have created two test, one is working fine but when a second test is executed it throws an error.
Below is my declared View
public interface IAddUpdateView : IView
{
string Type { get; set; }
string PageTitle { set; }
string Details { get; set; }
bool Active { get; set; }
}
Presenter
// BasePresenter is an abstract class contains abstract method with name Initialize()
public class MyPresenter: BasePresenter<IAddUpdateView >
{
private readonly IDatabaseLayer _databaselayer;
public MyPresenter(IAddUpdateView view, IDatabaseLayer databaseLayer) : base(view)
{
_databaselayer = databaseLayer;
}
public override void Initialize()
{ }
public void Initialize(string str)
{
string[] str1=Misc.DecryptURL(str);
View.Type = str1[0].ToString(); // ERROR LINE
if (View.Type.ToLower().Trim() == "add")
{
View.PageTitle = "Add New Task";
}
else if (View.Type.ToLower().Trim() == "edit")
{
}
}
}
Now I am working on creating unit test mocking the Presenter class to test the dependencies using Rhino mocks.
That's my test class with just two test methods. These test methods test when loading a View it calls appropriate Page Type.
When ADD type is called, it get the View.Type as "add" and when Edit type is called, it verifies for the specific object that is loaded.
[TestFixture]
public class MyPresenterTest
{
private IAddUpdateView _view;
private MyPresernter _controller;
[SetUp]
public void SetUp()
{
_view = MockRepository.GenerateMock<IAddUpdateView >();
_controller = new MyPresernter (_view, MockDataLayer());
}
[TearDown]
public void TearDown() { _controller = null; _view = null; }
// TEST 1
[Test]
public void When_Loading_for_Add_View_Panel_Return_Type_Add()
{
// Arrange
_view.Stub(x => x.Type).PropertyBehavior();
//Act
_controller.Initialize(GetURLWithAddValue());
// GetURLWithAddValue: This method get the URL with querystring contains value as "add"
//Assert
Assert.AreEqual("add",_view.Type);
}
TEST 2
// When this test method is run, It has the Type="edit", but in my
presenter View.Type (see LINE ERROR), my Type is null even I
assigned the values.
[Test]
public void When_Loading_for_Edit_View_Panel_Load_Correct_Object()
{
// Arrange
_view.Stub(x =>x.TaskDetails).PropertyBehavior();
//Act
Task o=new Task(){ TaskId=6, TASK_NAME="Task 6"};
_controller.Initialize(GetURLWithEditValue(o));
//Assert
Assert.AreEqual(o.TASK_NAME, _view.TaskDetails);
}
private static IDatabaseLayer MockDataLayer()
{
IDatabaseLayer obj = MockRepository.GenerateMock<IDatabaseLayer>();
MockTaskDataLayer a = new MockTaskDataLayer();
obj.Stub(x => x.GetList());
return obj;
}
}
Can someone guide me why Test 1 get passed and when Test 2 is executed, after assigning a value in View.Type (see LINE ERROR in MyPresenter class) it's still null??
Thanks,

Is there a way to Create nunit Setup with arguments

Is there a way to add arguments to an nunit setup method like this: public void SetUp(Point p = null) { /*code*/ }.
I tried it and got the following exception SetUp : System.Reflection.TargetParameterCountException : Parameter count mismatch
I think that your point is to avoid code duplication.
Try to extract base class with overriten method used in SetUp().
All derived class will execute tests from base class, with objects prepared in overriten OnSetUp()
[TestFixture]
public class BaseTestsClass
{
//some public/protected fields to be set in SetUp and OnSetUp
[SetUp]
public void SetUp()
{
//basic SetUp method
OnSetUp();
}
public virtual void OnSetUp()
{
}
[Test]
public void SomeTestCase()
{
//...
}
[Test]
public void SomeOtherTestCase()
{
//...
}
}
[TestFixture]
public class TestClassWithSpecificSetUp : BaseTestsClass
{
public virtual void OnSetUp()
{
//setup some fields
}
}
[TestFixture]
public class OtherTestClassWithSpecificSetUp : BaseTestsClass
{
public virtual void OnSetUp()
{
//setup some fields
}
}
Using parametrised TestFixture also can be usefull. Tests in class will be lunched per TestFixture, SetUp method also.
But remember that
Parameterized fixtures are (as you have discovered) limited by the fact that you can only use arguments that are permitted in attributes
Usage:
[TestFixture("some param", 123)]
[TestFixture("another param", 456)]
public class SomeTestsClass
{
private readonly string _firstParam;
private readonly int _secondParam;
public WhenNoFunctionCodeExpected(string firstParam, int secondParam)
{
_firstParam = firstParam;
_secondParam = secondParam;
}
[Test]
public void SomeTestCase()
{
...
}
}

Categories