Escrito el 02/06/2024
xUnit: Mocks
Para mockear objetos con la librería Moq.
Se crea un objeto Mock especificando el tipo de objeto a “falsear” especificando qué métodos o propiedades se van a mockear.
Luego se utiliza la propiedad .Object parta acceder al objeto mockeado.
Setup
Para configurar la respuesta para un método o propiedad dada.
using xUnit;
using Moq;
public class CalculatorTest {
[Fact]
public void Given_When_Then() {
var mockSource = new Mock<Source>();
mockSource
.Setup(x => x.Data) // la propiedad a mockear
.Returns(new object[]{ 1,2,3,4,5 }); // el valor que devolverá cuando se llame a la propiedad
var fakeObject = mockSource.Object; // obtener el objeto falso
Assert.Equal(new object[]{ 1,2,3,4,5 }, fakeObject.Data); // utilizar la propiedad falseada
}
[Fact]
public void Given_When_Then() {
var mockSource = new Mock<Source>();
mockSource
.Setup(x => x.GetData()) // la función a mockear
.Returns(new object[]{ 1,2,3,4,5 }); // el valor que devolverá cuando se llame a la propiedad
var fakeObject = mockSource.Object; // obtener el objeto falso
Assert.Equal(new object[]{ 1,2,3,4,5 }, fakeObject.Data); // utilizar la propiedad falseada
}
}
SetupSecuence
Para configuar la respuesta para una secuencia de llamadas.
using xUnit;
using Moq;
public class CalculatorTest {
[Fact]
public void Given_When_Then() {
var mockSource = new Mock<Source>();
mockSource
.SetupSecuence(x => x.Data)
.Returns(new object[]{ 1,2 }); // el valor que devolverá cuando se llame a la propiedad por 1era vez
.Returns(new object[]{ 1,2,3 }); // el valor que devolverá cuando se llame a la propiedad por 2da vez
.Returns(new object[]{ 1,2,3,4,5 }); // el valor que devolverá cuando se llame a la propiedad por 3era vez
var fakeObject = mockSource.Object;
Assert.Equal(new object[]{ 1,2 }, fakeObject.Data);
Assert.Equal(new object[]{ 1,2,3 }, fakeObject.Data);
Assert.Equal(new object[]{ 1,2,3,4,5 }, fakeObject.Data);
}
}
It
Cuando se mockea un método con parámetros se puede especificar qué valores puede tener ese parámetro
using xUnit;
using Moq;
public class CalculatorTest {
[Fact]
public void Given_When_Then() {
mockSource
.Setup(x => x.GetData("Sarasa"))// únicamente será mockeada el llamado con el valor exacto
.Returns(...);
mockSource
.Setup(x => x.GetData(It.IsAny<string>()))// puede ser cualquier valor de un tipo
.Returns(...);
mockSource
.Setup(x => x.GetData(It.Is<ComplexObject>(x => x.Age > 18)))// para que se mockea los llamado con parámetros cuya edad sea mayor de edad
.Returns(...);
}
}
Verify y Verifiable
Se puede agregar una validación para chequear que el método será (en la sección arrange) o fué llamado (en la sección assert)
using xUnit;
using Moq;
public class CalculatorTest {
[Fact]
public void Given_When_Then() {
// arrange
mockSource
.Setup(...)
.Returns(...)
.Verifiable(); // valida que se haya llamado al menos una vez
// act
...
// assert
mockSource
.Setup(...)
.Verify(Times.Once)// valida que se haya llamado una sóla vez (ni más ni menos)
}
}