Моты должны использоваться в качестве замены для зависимостей вокруг того, что вы пытаетесь проверить.
Что касается вашего теста, просто протестируйте фактическое поведение вашего класса, то есть не попробуй использовать приватные методы и сеттеры. В любом случае, использование класса для проверки не является допустимым подходом.
Например:
Если вы хотите проверить класс Test
:
[TestClass]
public class TestTests
{
[TestMethod]
public void Calc_WhenPropIsSetTo5_Returns10()
{
/**
* Seems this is what you want to test (see name of methods),
* and I don't think it is a good idea, as your setter is private.
* Since it's not a "public" behavior, you could either
*
* a) have the setter as internal for testing purposes,
*
* b) (my recommendation) go for the two other tests below instead;
* this will actually test the exposed behavior of the class.
*
* c) circumvent the accessibility (by using a library or using
* Reflection directly) to set the value of the prop.
* See your own answer for an example.
*/
}
[TestMethod]
public void Calc_WhenCreatedWith5_Returns10()
{
// Arrange
var testSubject = new Test(5); // if the prop is set by constructor... otherwise arrange in the proper way.
// Act
var actualResult = testSubject.Calc();
// Assert
Assert.AreEqual(expected: 10, actualResult)
}
[TestMethod]
public void Prop_WhenCreatedWith5_IsSetTo5()
{
// Arrange
var testSubject = new Test(5);
// Act
var actualResult = testSubject.Prop;
// Assert
Assert.AreEqual(expected: 5, actualResult)
}
}
Если вы хотите протестировать что-то, использующее ITest.Calc()
,
, то в своем фактическом коде вы должны
1 - зависеть от интерфейса ITest
, а не при реализации Test
2 - иметь зависимость , внедренную в тестируемый класс, чтобы можно было заменить обычную реализацию Test
на Mock<ITest>.Object()
public class ClassThatUsesTest
{
private readonly ITest _test;
public ClassThatUsesTest(ITest test)
{
_test = test;
}
public int SomeFunction()
{
if (_test.Calc() == 10)
{
return 42;
}
else
{
return 0;
}
}
}
[TestClass]
public class ClassThatUsesTestTests
{
[TestMethod]
public void SomeFunction_WhenTestCalcReturns10_Returns42()
{
// Arrange
var testMock = new Mock<ITest>();
testMock.Setup(x => x.Calc()).Returns(10);
var testSubject = new ClassThatUsesTest(testMock.Object);
var expectedResult = 42;
// Act
var actualResult = testSubject.SomeFunction();
//
Assert.AreEqual(expectedResult, actualResult);
}
}
В последнем примере вы видите, что макеты помогают нам изолировать тест без зависимости от фактических деталей реализации класса Test
. Даже если внезапно фактический Test
сломается или изменится (например, вам нужно пройти 6 вместо 5, чтобы получить 10), метод теста не имеет значения.