Я пытаюсь протестировать логику от некоторых существующих классов. Не возможно осуществить рефакторинг классы в настоящее время, поскольку они очень сложны и в производстве.
То, что я хочу сделать, создают фиктивный объект и тестируют метод, который внутренне называет другой метод, который очень трудно дразнить.
Таким образом, я хочу просто установить поведение для вторичного вызова метода.
Но когда я устанавливаю поведение для метода, код метода вызывается и перестал работать.
Я пропускаю что-то, или разве это просто не возможно протестировать, не осуществляя рефакторинг класс?
Я попробовал все различные ложные типы (Strick, Тупик, Динамический, Частичный ect.), но они все заканчивают тем, что назвали метод, когда я пытаюсь настроить поведение.
using System;
using MbUnit.Framework;
using Rhino.Mocks;
namespace MMBusinessObjects.Tests
{
[TestFixture]
public class PartialMockExampleFixture
{
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
//setup mocks
MockRepository mocks = new MockRepository();
var mockTestClass = mocks.StrictMock<TestClass>();
//record beahviour *** actualy call into the real method stub ***
Expect.Call(mockTestClass.MethodToMock(param)).Return(true);
//never get to here
mocks.ReplayAll();
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
}
public class TestClass
{
public bool MethodToMock(string param)
{
//some logic that is very hard to mock
throw new NotImplementedException();
}
public bool MethodIWantToTest(string param)
{
//this method calls the
if( MethodToMock(param) )
{
//some logic i want to test
}
return true;
}
}
}
}
MethodToMock не является виртуальным и поэтому не может быть имитирующим. То, что вы хотите сделать, возможно с частичным макетом (я делал это в случаях, похожих на ваш), но метод, который вы хотите имитировать, должен быть либо частью реализации интерфейса, либо быть помечен как виртуальный. В противном случае вы не сможете издеваться над этим с помощью Rhino.Mocks.
Я рекомендую не издеваться над методами в тестируемом классе, но ваша ситуация может быть уникальна тем, что вы не можете рефакторить класс, чтобы сделать его более удобным для тестирования в настоящее время. Вы можете попробовать явно создать делегат, чтобы предотвратить вызов метода при настройке вызова.
Expect.Call( delegate { mockTestClass.MethodToMock(param) } ).Return(true);
Или перейти на использование синтаксиса AAA, опустив устаревшие конструкции.
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
var mockTestClass = MockRepository.GenerateMock<TestClass>();
mockTestClass.Expect( m => m.MethodToMock(param) ).Return( true );
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
mockTestClass.VerifyAllExpectations();
}