Tengo una prueba como esta:
    [TestCase("~/page/myaction")]
    public void Page_With_Custom_Action(string path) {
        // Arrange
        var pathData = new Mock<IPathData>();
        var pageModel = new Mock<IPageModel>();
        var repository = new Mock<IPageRepository>();
        var mapper = new Mock<IControllerMapper>();
        var container = new Mock<IContainer>();
        container.Setup(x => x.GetInstance<IPageRepository>()).Returns(repository.Object);
        repository.Setup(x => x.GetPageByUrl<IPageModel>(path)).Returns(() => pageModel.Object);
        pathData.Setup(x => x.Action).Returns("myaction");
        pathData.Setup(x => x.Controller).Returns("page");
        var resolver = new DashboardPathResolver(pathData.Object, repository.Object, mapper.Object, container.Object);
        // Act
        var data = resolver.ResolvePath(path);
        // Assert
        Assert.NotNull(data);
        Assert.AreEqual("myaction", data.Action);
        Assert.AreEqual("page", data.Controller);
    }GetPageByUrlfunciona dos veces en mi DashboardPathResolver, ¿cómo puedo decirle a Moq que regrese nullla primera y pageModel.Objectla segunda?
                    
                        c#
                                unit-testing
                                nunit
                                moq
                                
                    
                    
                        marcus
fuente
                
                
            fuente

SetupSequence()no funciona conCallback(). Si solo lo hiciera, uno podría verificar las llamadas al método simulado en una forma de "máquina de estado".SetupSequencesolo funciona para dos llamadas, pero ¿qué puedo hacer si necesito más de dos llamadas?SetupSequencese puede usar para un número arbitrario de llamadas. El primer ejemplo que di devuelve una secuencia de 5 llamadas.Las respuestas existentes son geniales, pero pensé en agregar mi alternativa que solo usa
System.Collections.Generic.Queuey no requiere ningún conocimiento especial del marco de trabajo burlón, ¡ya que no tenía ninguno cuando lo escribí! :)Luego...
fuente
Exceptioncomo no puedeEnqueue. PeroSetupSequencefuncionará (vea la respuesta de @stackunderflow, por ejemplo).Dequeue()lugar de soloDequeue, estaría correcto.Agregar una devolución de llamada no funcionó para mí, utilicé este enfoque en su lugar http://haacked.com/archive/2009/09/29/moq-sequences.aspx y terminé con una prueba como esta:
fuente
Puede usar una devolución de llamada al configurar su objeto simulado. Eche un vistazo al ejemplo de Moq Wiki ( http://code.google.com/p/moq/wiki/QuickStart ).
Su configuración podría verse así:
fuente
Setup()volver a hacer la llamada y obtenerReturn()un valor diferente.Ahora puede usar SetupSequence. Ver esta publicación: http://codecontracts.info/2011/07/28/moq-setupsequence-is-great-for-mocking/
fuente
Accedido aquí por el mismo tipo de problema con requisitos ligeramente diferentes.
Necesito obtener diferentes valores de retorno de simulacros basados en diferentes valores de entrada y encontré una solución que IMO es más legible ya que usa la sintaxis declarativa de Moq (linq to Mocks).
fuente
da.GetFromDb(0) == new Account { ..None.. && da.GetFromDb(1) == new Account { InActive } && ..., sinIt.Is-lambda requerido.La respuesta aceptada , así como la respuesta SetupSequence , maneja las constantes de retorno.
Returns()tiene algunas sobrecargas útiles donde puede devolver un valor basado en los parámetros que se enviaron al método simulado. Basado en la solución dada en la respuesta aceptada, aquí hay otro método de extensión para esas sobrecargas.Desafortunadamente, el uso del método requiere que especifique algunos parámetros de plantilla, pero el resultado sigue siendo bastante legible.
Crear sobrecargas para el método de extensión con múltiples parámetros (
T2,T3, etc.) si es necesario.fuente